Маскируйте белый цвет из PNG или GIF изображения, перетяните его на холст любым цветом - PullRequest
4 голосов
/ 11 июня 2011

Источник - PNG или GIF, где пиксели, которые должны быть «раскрашены», - белые. Фон может быть как черным, так и прозрачным, в зависимости от того, что проще.

Теперь я хотел бы вырезать прямоугольную часть источника и AND с помощью цвета палитры (gif) или цвета RGB (png) «кисти», чтобы «штамповать» его на TImage / TCanvas с этим цветом.

Вероятно, один из тех ленивых вопросов, где RTFM будет делать. Но если у вас есть хорошее решение, пожалуйста, поделитесь:)

Я попробовал Daud's PNGImage lib, но у меня даже не получается загрузить исходное изображение. Есть ли хитрость в его использовании?

Решение должно работать на D7 и выше, XP и выше.

1 Ответ

1 голос
/ 13 июня 2011

я понимаю, что вы хотите изменить белый цвет другим цветом? если это так, я думаю, вы должны проверить изображение пиксель за пикселем и проверить, какой цвет является пикселем, и изменить его, если он белый.

вот как вы можете перебрать изображение

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;

Вот код, который показывает, как читать значения Red и Blue и переключать их.

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

но это только для растровых изображений.

если это полезно, попробуйте преобразовать ваше изображение в растровое изображение и затем манипулировать им.

...