Jump to content
RD_CEDES

Bitmaps alpha has less effect the whiter a pixel is

Recommended Posts

Hello everyone

 

Bitmaps do show a weird behavior. The whiter a pixel gets, the less effect setting the alpha has.

 

Here is some code to reproduce the situation. It (should) generate a bitmap that goes from black (top) to white (bottom) and from 0 alpha (left) to 255 alpha (right).

 

{
Should generates a bitmap with:
  - a grayscale gradient on the y-axis from black (top) to white (bottom)
  - an alpha gradient on the x-axis from 0 (left) to 255 (right)

But the whiter a pixel gets, the less effect the alpha has.
}
procedure TfrmMain.FormCreate(Sender: TObject);
const
  RES_X = 512;
  RES_Y = 512;
var
  bmpData: TBitmapData;
  paca: PAlphaColorArray;
  c: TAlphaColor;
begin
  img.Bitmap := TBitmap.Create(RES_X, RES_Y);
  img.Bitmap.Map(TMapAccess.Write, bmpData);
  for var y := 0 to RES_Y - 1 do
  begin
    paca := bmpData.GetScanline(y);
    for var x := 0 to RES_X - 1 do
    begin
      var g := Byte(Round($FF / RES_Y * y)); // Varying gray component based on y coordinate
      var a := Byte(Round($FF / RES_X * x)); // Varying alpha component based on x coordinate
      c := (a shl 24) or (g shl 16) or (g shl 8) or g;
      paca[x] := c;
    end;
  end;
  img.Bitmap.Unmap(bmpData); // Not as expected
  img.Bitmap.SaveToFile('test.png'); // PNGs look exactly as expected
end;

 

When saving the bitmap as PNG, the transparency is exactly as expected (attached "Saved_as_PNG_added_red_background.png"), but the image shown on the form (attached "Form_screenshot.png") behaves differently.

 

Helping words on how to change the opacity of white pixels are highly appreciated.

 

What I'm trying to do is having an image (that is updated every 50 ms) showing the history of a sensor. The data is shown as white pixels, and the further in the past / on the left the data is, the more transparent the pixels shall get.

 

Form_screenshot.png

Saved_as_bitmap_no_alpha_add_all.bmp

Saved_as_PNG_added_red_background.png

Edited by RD_CEDES

Share this post


Link to post

Thank you very much Sir! That works!

 

{
Generates a bitmap with:
  - a grayscale gradient on the y-axis from black (top) to white (bottom)
  - an alpha gradient on the x-axis from 0 (left) to 255 (right)
}
procedure TfrmMain.FormCreate(Sender: TObject);
const
  RES_X = 512;
  RES_Y = 512;
var
  bmpData: TBitmapData;
  paca: PAlphaColorArray;
  c: TAlphaColor;
  a, g: UInt8;
begin
  img.Bitmap := TBitmap.Create(RES_X, RES_Y);
  img.Bitmap.Map(TMapAccess.Write, bmpData);
  for var y := 0 to RES_Y - 1 do
  begin
    paca := bmpData.GetScanline(y);
    for var x := 0 to RES_X - 1 do
    begin
      a := Byte(Round($FF / RES_X * x)); // Varying alpha component based on x coordinate
      g := MulDivInt64(a, 255, 255);
      c := (a shl 24) or (g shl 16) or (g shl 8) or g;
      paca[x] := c;
    end;
  end;
  img.Bitmap.Unmap(bmpData);
  img.Bitmap.SaveToFile('test.png');
end;

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×