Search code examples
delphicolorsmaskblit

Mask out white color from PNG or GIF image, blit it to canvas using any color


Source is either PNG or GIF where the pixels that should be "colorized" are white. Background can be either black or transparent, whichever is easiest.

Now I'd like to cut out a rectangular part of the source, and AND it with the palette color (gif) or RGB color (png) of the "brush", to "stamp" it out on a TImage/TCanvas with that color.

Probably one of those lazy questions where RTFM would do. But if you have a nice solution please share :)

I tried Daud's PNGImage lib, but I can't even get it loading the source image. Is there a trick to using it?

The solution needs to work on D7 and up, XP and up.


Solution

  • do i understand you want to change the white color with some other color? if that is so i think you should check the image pixel by pixel and check what color is the pixel and change it if is white.

    thats how you can loop through image

    var
      iX  : Integer;
      Line: PByteArray;
    ...
      Line := Image1.ScanLine[0]; // We are scanning the first line
      iX := 0;
      // We can't use the 'for' loop because iX could not be modified from
      // within the loop
      repeat
        Line[iX]     := Line[iX] - $F; // Red value
        Line[iX + 1] := Line[iX] - $F; // Green value
        Line[iX + 2] := Line[iX] - $F; // Blue value
        Inc(iX, 3); // Move to next pixel
      until iX > (Image1.Width - 1) * 3;
    

    Here's code that show how to reads the Red and Blue values and switched them.

    var
      btTemp: Byte; // Used to swap colors
      iY, iX: Integer;
      Line  : PByteArray;
    ...
      for iY := 0 to Image1.Height - 1 do begin
        Line := Image1.ScanLine[iY]; // Read the current line
        repeat
          btSwap       := Line[iX];     // Save red value
          Line[iX]     := Line[iX + 2]; // Switch red with blue
          Line[iX + 2] := btSwap;       // Switch blue with previously saved red
          // Line[iX + 1] - Green value, not used in example
          Inc(iX, 3);
        until iX > (Image1.Width - 1) * 3;
      end;
      Image1.Invalidate; // Redraw bitmap after everything's done
    

    but this is for bitmap image only.

    if this is useful try to convert your image to bitmap and from then manipulate it.