Drawing bitmap by pixel

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Drawing bitmap by pixel

Ryan Joseph
I’d like to draw a bitmap pixel by pixel then save to disk but I can’t understand the docs available online. I know there’s a BGRABitmap class with direct pixel access but I wasn’t able to find the unit in my FPC distribution.

I used the image canvas before to draw bitmap fonts so I have this code working. Is there anyway to set a pixel using TFPImageCanvas? I also couldn’t figure out how to set the brush color (confusing reference once again). It looks like Lazarus has good classes but they’re so hard to discover and learn because the references aren’t complete and in one place.

What’s the best way to do this? Thanks.

procedure DrawBitmap;
var
image: TFPMemoryImage;
canvas: TFPImageCanvas;
writer: TFPWriterPNG;
begin
image := TFPMemoryImage.Create(100, 100);
 canvas := TFPImageCanvas.Create(image);

canvas.Clear;
canvas.Brush.FPColor := colRed;  // how do I set the color as an RGB?
canvas.Rectangle(0, 0, 1, 1); // how do I draw a single pixel?

writer := TFPWriterPNG.Create;
 image.SaveToFile('bitmap.png', writer);
end;

Regards,
Ryan Joseph


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Drawing bitmap by pixel

Felipe Monteiro de Carvalho
On Thu, Jan 19, 2017 at 3:59 PM, Ryan Joseph <[hidden email]> wrote:
> I used the image canvas before to draw bitmap fonts so I have this code
> working. Is there anyway to set a pixel using TFPImageCanvas?

Use the Colors property, it is fast:

property Colors [x,y:integer] : TFPColor read GetColor write SetColor;

> canvas.Brush.FPColor := colRed;  // how do I set the color as an RGB?

Use this function:

function FPColor (r,g,b,a:word) : TFPColor;

fcl-image is from Free Pascal, not from Lazarus, but in
lcl/lazcanvas.pas there is TLazCanvas which extends TFPImageCanvas
adding convenience functions for example for alpha blending among
other stuff.

--
Felipe Monteiro de Carvalho
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Drawing bitmap by pixel

Graeme Geldenhuys-6
In reply to this post by Ryan Joseph
On 2017-01-19 14:59, Ryan Joseph wrote:
> Is there anyway to set a pixel using TFPImageCanvas?

It is slightly confusing. If you are using an Indexed image, then use
the Pixels[] property. If you are not using an Indexed image, then use
the Colors[] property.

Attached is an example program that generates a Minecraft like grass
block (texture) and then outputs it to a PNG file. I hope the example helps.

Regards,
  Graeme

--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

output-1.png (6K) Download Attachment
project1.lpr (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Drawing bitmap by pixel

Ryan Joseph

> On Jan 20, 2017, at 7:20 AM, Graeme Geldenhuys <[hidden email]> wrote:
>
> It is slightly confusing. If you are using an Indexed image, then use
> the Pixels[] property. If you are not using an Indexed image, then use
> the Colors[] property.

Thanks guys,

Here’s the new program based on your example but it still just outputs a pure black image.

procedure Draw;
var
        image: TFPCustomImage;
        canvas: TFPImageCanvas;
        writer: TFPWriterPNG;
        x, y: integer;
begin
        image := TFPCompactImgRGB8Bit.Create(100, 100);
        image.UsePalette := False;
 
        for x := 0 to image.Width-1 do
        for y := 0 to image.Height-1 do
                image.Colors[x, y] := FPColor(255, 0, 0, 255);

        writer := TFPWriterPNG.Create;
        writer.Indexed := False;
  image.SaveToFile('bitmap.png', writer);
end;


Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Drawing bitmap by pixel

Ryan Joseph

> On Jan 20, 2017, at 8:31 AM, Ryan Joseph <[hidden email]> wrote:
>
> Thanks guys,
>
> Here’s the new program based on your example but it still just outputs a pure black image.

never mind! The max color value is 65535. I thought it was 1.0 or 255. Got it working now. Thanks again.

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Drawing bitmap by pixel

Graeme Geldenhuys-6
On 2017-01-20 01:50, Ryan Joseph wrote:
> The max color value is 65535. I thought it was 1.0 or 255.

The FPImage implementation supports 16bit color channels (a bit of
future proofing that confuses many). Most programs and images use 8bits
per channel. Each color channel is thus a WORD size, not a BYTE size.

That is why my example program does the following:

      // duplicate the data to fill a WORD size channel
      r := (r shl 8) or r;
      g := (g shl 8) or g;
      b := (b shl 8) or b;

eg: if r was initial $00AC  (by using Random($FF) to populate it), I
then duplicate the initial value to fill the WORD size value, and the
above code will make r = $ACAC. Strictly not 100% correct thing to do,
but seems to work with FPImage.

Regards,
  Graeme

--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

My public PGP key:  http://tinyurl.com/graeme-pgp
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal