Старые новости, см. Efg2.com

зите исходный код здесь:http://www.eyeClaxton.com/download/delphi/ColorSwap.zip

Да, я хочу преобразовать что-то «в основном голубое» во что-то «в основном зеленое».

Я хотел бы взять исходное растровое изображение (светло-голубой) и изменить цвета (Pixel by Pixel) на отношение эквивалентности красного, зеленого, синего и серого. Чтобы понять, что я имею в виду, я включил исходный код и снимок экрана. Любая помощь будет принята с благодарностью. Если вам нужна дополнительная информация, пожалуйста, не стесняйтесь спрашивать.

Если бы вы могли взглянуть на приведенный ниже код, у меня есть три функции, по которым мне нужна помощь. Функции «RGBToRed, RGBToGreen и RGBToRed» я не могу придумать правильные формулы.

unit MainUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TMainFrm = class(TForm)
    Panel1: TPanel;
    Label1: TLabel;
    Panel2: TPanel;
    Label2: TLabel;
    Button1: TButton;
    BeforeImage1: TImage;
    AfterImage1: TImage;
    RadioGroup1: TRadioGroup;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainFrm: TMainFrm;

implementation

{$R *.DFM}
function RGBToGray(RGBColor: TColor): TColor;
var
  Gray: Byte;
begin
  Gray := Round(
    (0.90 * GetRValue(RGBColor)) +
    (0.88 * GetGValue(RGBColor)) +
    (0.33 * GetBValue(RGBColor)));

  Result := RGB(Gray, Gray, Gray);
end;

function RGBToRed(RGBColor: TColor): TColor;
var
  Red: Byte;
begin
  // Not sure of the algorithm for this color
  Result := RGB(Red, Red, Red);
end;

function RGBToGreen(RGBColor: TColor): TColor;
var
  Green: Byte;
begin
  // Not sure of the algorithm for this color
  Result := RGB(Green, Green, Green);
end;

function RGBToBlue(RGBColor: TColor): TColor;
var
  Blue: Byte;
begin
  // Not sure of the algorithm for this color
  Result := RGB(Blue, Blue, Blue);
end;

procedure TMainFrm.FormCreate(Sender: TObject);
begin
  BeforeImage1.Picture.LoadFromFile('Images\RightCenter.bmp');
end;

procedure TMainFrm.Button1Click(Sender: TObject);
var
  Bitmap: TBitmap;
  I, X: Integer;
  Color: Integer;
begin
  Bitmap := TBitmap.Create;
  try
    Bitmap.LoadFromFile('Images\RightCenter.bmp');

    for X := 0 to Bitmap.Height do
    begin
      for I := 0 to Bitmap.Width do
      begin
        Color := ColorToRGB(Bitmap.Canvas.Pixels[I, X]);

        case Color of
          $00000000: ;   // Skip any Color Here!
        else
          case RadioGroup1.ItemIndex of
            0: Bitmap.Canvas.Pixels[I, X] := RGBToBlue(Color);
            1: Bitmap.Canvas.Pixels[I, X] := RGBToRed(Color);
            2: Bitmap.Canvas.Pixels[I, X] := RGBToGreen(Color);
            3: Bitmap.Canvas.Pixels[I, X] := RGBToGray(Color);
          end;
        end;
      end;
    end;
    AfterImage1.Picture.Graphic := Bitmap;
  finally
    Bitmap.Free;
  end;
end;

end.

Хорошо, я прошу прощения за то, что не сделал это яснее. Я пытаюсь взять растровое изображение (синего цвета) и заменить синие пиксели другим цветом. Как на снимках ниже.

 eyeClaxton10 янв. 2011 г., 01:55
Если бы вы могли взглянуть на приведенный выше код, у меня есть три функции, по которым мне нужна помощь. Функции «RGBToRed, RGBToGreen и RGBToRed» я не могу придумать правильные формулы.
 eyeClaxton10 янв. 2011 г., 03:10
Хорошо, я перегруппируюсь и попробую задать вопрос другим способом позже.
 Wouter van Nifterick10 янв. 2011 г., 01:40
Хорошо, мне нравится лицо, которое вы предоставили скриншот и код, но я не получаю то, что вы хотите от нас. В чем вопрос, или какая часть работает не так, как вы хотите?
 Andreas Rejbrand10 янв. 2011 г., 02:47
Таким образом, вы хотите, чтобы все красное тоже стало зеленым (посмотрите на Х окна). Есть тысяча способов превратить что-то «в основном голубое» в нечто «в основном зеленое», надеюсь, вы это знаете.
 Rob Kennedy10 янв. 2011 г., 01:03
Я не понимаю Каким образом предоставленный вами код уже не выполняет то, что вам нужно?

Ответы на вопрос(2)

ам следует рассмотреть возможность использования свойства "Scanline", чтобы получить код примерно на 2 уровня быстрее.http://blogs.embarcadero.com/pawelglowacki/2010/04/15/39051 содержит примеры кода, как это сделать.

Успех!

 Free Consulting10 янв. 2011 г., 16:18
Старые новости, см. Efg2.com
Решение Вопроса

чего вы пытаетесь достичь. Во-первых, при чем тут вопросотношения эквивалентности?

Во-вторых, код

function RGBToRed(RGBColor: TColor): TColor;
var
  Red: Byte;
begin
  // Not sure of the algorithm for this color
  Result := RGB(Red, Red, Red);
end;

бессмысленно. Возвращаемое значение не определено.RGB Функция принимает интенсивность красного, зеленого и синего в диапазоне от 0 до 255 и возвращаетTColor имея эти компоненты. Например,RGB(255, 0, 0) чистый красный, то есть 255 красных, 0 зеленых и 0 синих. В приведенном выше коде, однако,Red не инициализируется, такResult может быть любого серого цвета (в зависимости от того, чтоRed бывает). [И, как вы, наверное, знаете, если вы смешиваете равное количество красного, зеленого и синего, как вы делаете, вы получаете серый.] Например,Red может случиться, что 45 раз вы запустите приложение, и тогда результатом будет серый цветRGB(45, 45, 45), В следующий раз это может быть 163.

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

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

grey := (GetRValue(Color) + GetGValue(Color) + GetBValue(Color)) div 3;

Есть и другие способы сделать это (в результате получаются слегка отличающиеся изображения в оттенках серого, но это самый простой (и самый быстрый)). (Например, вы можете преобразовать цвет из RGB в HSV или HSL, а затем установить насыщенность равной нулю.)

Обновить

Я думаю, что я вижу, что вы хотите сделать. Может быть, вы хотите извлечь красный, зеленый и синий каналы. То есть вы хотите преобразовать каждый пиксельRGB(R, G, B) вRGB(R, 0, 0) в красном корпусе. Если это то, что вы хотите сделать, то вы должны сделать

function RGBToRed(RGBColor: TColor): TColor;
begin
  Result := RGB(GetRValue(RGBColor), 0, 0);
end;

и аналогично для других компонентов, то есть

function RGBToGreen(RGBColor: TColor): TColor;
begin
  Result := RGB(0, GetGValue(RGBColor), 0);
end;

а также

function RGBToBlue(RGBColor: TColor): TColor;
begin
  Result := RGB(0, 0, GetBValue(RGBColor));
end;

Или, может быть

Или, может быть, вы просто хотите сделать изображение серым, а затем «покрасить» его в красный (или зеленый, или синий). Тогда вам нужна тяжелая техника. Теоретически, вы хотите заменить каждый пиксель изHSV(h, s, v) вHSV(0, s, v) в красном случае,HSV(120, s, v) в зеленом корпусе иHSV(240, s, v) в синем корпусе. Или, может быть, вы также хотите установить насыщенностьs до 1.

Я использую следующие процедуры для преобразования между RGB и HSV:

function RGBToHSV(const Color: TRGB): THSV;
var
  cmax, cmin, cdiff: real;
begin
  cmax := MaxComponent(Color);
  cmin := MinComponent(Color);
  cdiff := cmax - cmin;

  with Color, result do
  begin

    // Hue
    if cmax = cmin then
      hsvHue := 0
    else if cmax = rgbRed then
      hsvHue := (60 * (rgbGreen - rgbBlue) / cdiff)
    else if cmax = rgbGreen then
      hsvHue := (60 * (rgbBlue - rgbRed) / cdiff) + 120
    else
      hsvHue := (60 * (rgbRed - rgbGreen) / cdiff) + 240;

    hsvHue := Fix360(hsvHue);

    // Saturation
    if cmax = 0 then
      hsvSaturation := 0
    else
      hsvSaturation := 1 - cmin / cmax;

    // Value
    hsvValue := cmax;

  end;

end;

а также

function HSVToRGB(const Color: THSV): TRGB;
var
  hi: integer;
  f, q, p, t: real;
begin

  with Color do
  begin

    hi := floor(hsvHue / 60) mod 6;
    f := hsvHue / 60 - floor(hsvHue / 60);
    p := hsvValue * (1 - hsvSaturation);
    q := hsvValue * (1 - f * hsvSaturation);
    t := hsvValue * (1 - (1 - f) * hsvSaturation);

    case hi of
      0: result := RGB(hsvValue, t, p);
      1: result := RGB(q, hsvValue, p);
      2: result := RGB(p, hsvValue, t);
      3: result := RGB(p, q, hsvValue);
      4: result := RGB(t, p, hsvValue);
      5: result := RGB(hsvValue, p, q);
    end;

  end;

end;

где

type
  TRGB = record
    rgbRed,            // red intensity between 0 and 1
    rgbGreen,          // green intensity between 0 and 1
    rgbBlue: double;   // blue intensity between 0 and 1
  end;

  THSV = record
    hsvHue,            // hue angle between 0 and 360
    hsvSaturation,     // saturation between 0 (grey) and 1 (full colour)
    hsvValue: double;  // value between 0 (dark) and 1 ("normal")
  end;

Конечный результат, в зеленом случае, будет похож

Оттенок установлен на 120 http://english.rejbrand.se/algosim/manual/pmproc/fixHue120.jpg

в первом случае (оттенок установлен на 120) и

Для оттенка установлено значение 120, а для насыщенности - 1 http://english.rejbrand.se/algosim/manual/pmproc/monochromatic120.jpg

в последнем случае (оттенок установлен на 120, насыщенность установлена ​​на 1).

Или, возможно,

Ваш вопрос очень смелый, даже с правкой. Вы хотите преобразовать что-то «в основном синее» во что-то «в основном зеленое». Но есть тысячи способов сделать это! Очень простой способ, конечно, просто поменять синий и зеленый каналы, то есть заменитьRGB(r, g, b) с участиемRGB(r, b, g)или, явно,

function SwapBlueGreen(Color: TColor): TColor;
begin
  result := RGB(GetRValue(Color), GetBValue(Color), GetGValue(Color));
end;

Тогда вы получите что-то вроде

R и G каналы поменялись местами http://english.rejbrand.se/algosim/manual/pmproc/swapRG.jpg

где красный и зеленый каналы поменялись местами. Обратите внимание, что красная палочка теперь зеленая, а зеленая трава теперь красная. Что белое остается белым.

в заключение

Добро пожаловать в мир растровых манипуляций! Есть много простых и забавных вещей. Еще несколько моих примеров:http://english.rejbrand.se/algosim/manual/pmproc/pmproc.html

 user117574315 мая 2012 г., 17:58
+1 Блестящий исчерпывающий ответ! возможно, однажды я смогу понять логику такого кода :)
 David11 янв. 2011 г., 07:15
+1, хороший ответ!
 eyeClaxton10 янв. 2011 г., 02:52
Да, я хочу преобразовать что-то «в основном голубое» во что-то «в основном зеленое».

Ваш ответ на вопрос