Конференция "Игры" » Обратная функцыя к RGB() существует? [Delphi, Windows]
 
  • lubass © (22.10.07 20:25) [0]
    Как мне достать значения цветов (красного, зеленого и синего) из цвета?
  • homm © (22.10.07 20:32) [1]
    var
     r,g,b: byte;
     color: TColor;
    begin
     r := byte(color);
     g := byte(color shr 8);
     b := byte(color shr 16);
    end;

  • Pa5ha © (22.10.07 20:32) [2]
    function GetRValue(color: tcolor): byte;
    и т.д.
  • lubass © (22.10.07 20:38) [3]
    Спосибо
  • antonn © (22.10.07 20:40) [4]
    дежавю? :)
  • rts111 © (22.10.07 23:21) [5]
    type

    TColor4b = record
     r,g,b,a :byte;

    ...

    var
    color: TColor;
    r: byte;
    ...

    begin

    ...
    r := TColor4b (color).r;
    ...

    end;
  • @!!ex © (23.10.07 11:40) [6]
    > [3] lubass ©   (22.10.07 20:38)

    варианты [1] и [2] - идеентичны. Но я бы предпочел первый, поскольку нет лишнего вызова процедур.
  • rts111 © (23.10.07 12:37) [7]

    > @!!ex ©   (23.10.07 11:40) [6]


    А чем тебе мой вариант не нравится, там бообще обращение напрямую к значению без shr.

    Правка:
    TColor4b = record
    r,g,b,a :byte;
    end;
  • antonn © (23.10.07 13:42) [8]

    > А чем тебе мой вариант не нравится, там бообще обращение
    > напрямую к значению без shr.

    без shr написано, или без shr откомпилируется?
  • rts111 © (23.10.07 14:35) [9]

    > antonn ©   (23.10.07 13:42) [8]
    >
    > > А чем тебе мой вариант не нравится, там бообще обращение
    >
    > > напрямую к значению без shr.
    >
    > без shr написано, или без shr откомпилируется?


    Именно без shr откомпилируется.
  • @!!ex © (23.10.07 18:03) [10]
    > [7] rts111 ©   (23.10.07 12:37)

    Ну хотя бы потому, что придется приведение типов использовать при переходе TColor<->TColor4b.
    а так... конечно лучший вариант. С ним лично я и работаю. Только не с WinAPI, а с OpenGL, там так удобнее.
  • homm © (23.10.07 19:19) [11]
    > [7] rts111 ©   (23.10.07 12:37)
    > А чем тебе мой вариант не нравится, там бообще обращение
    > напрямую к значению без shr.

    procedure SwapChanels(BMP: TBitmap);
    type
      ADWORD = array [0..0] of DWORD;
    var
      i, j: Integer;
      Pix: DWORD;
      Line: ^ADWORD;
    begin
      for i := 0 to BMP.Height-1 do begin
        Line := BMP.ScanLine[i];
        for j := 0 to BMP.Width-1 do begin
          Pix := Line[j];
          //Line[j] := GetBValue(Pix) + (GetGValue(Pix) shl 8) + (GetRValue(Pix) shl 16);    // 1200 mSec
          //Line[j] := byte(Pix shr 16) + (byte(Pix shr 8) shl 8) + (byte(Pix) shl 16);    // 300 mSec
          //Line[j] :=  TRGBQuad(Pix).rgbRed + (TRGBQuad(Pix).rgbGreen shl 8) + (TRGBQuad(Pix).rgbBlue shl 16);  //650 mSec
          TRGBQuad(Line[j]).rgbBlue := TRGBQuad(Pix).rgbRed;        // 610 mSec
          TRGBQuad(Line[j]).rgbGreen := TRGBQuad(Pix).rgbGreen;
          TRGBQuad(Line[j]).rgbRed := TRGBQuad(Pix).rgbBlue;
        end;
      end;
    end;


    procedure TForm1.Button1Click(Sender: TObject);
    type
      ADWORD = array [0..0] of DWORD;
    var
      i, T: Integer;
    begin
      Image1.Picture.Bitmap := TBitmap.Create;
      Image1.Picture.Bitmap.LoadFromFile('C:\1.bmp');
      Image1.Picture.Bitmap.PixelFormat := pf32bit;

      T := GetTickCount;
      for i := 0 to 98 do
        SwapChanels(Image1.Picture.Bitmap);
      ShowMessage(IntToStr(GetTickCount-T));

    end;

  • rts111 © (23.10.07 23:24) [12]

    > homm ©   (23.10.07 19:19) [11]


    procedure SwapChanels(BMP: TBitmap);
    type
     ADWORD = array [0..0] of DWORD;
    var
     i, j: Integer;
     //Pix: DWORD;
     Line: ^ADWORD;
     Temp: byte;
    begin
     for i := 0 to BMP.Height-1 do
     begin
       Line := BMP.ScanLine[i];
       for j := 0 to BMP.Width-1 do
       with TRGBQuad(Line[j]) do
       begin
        Temp    := rgbRed;             // 1 mSec!!!  :)
        rgbRed  := rgbBlue;
        rgbBlue := Temp;
       end;
     end;
    end;
  • Pa5ha © (24.10.07 01:32) [13]
    операции битового сдвига выполняюца за один такт процессора и этим все сказано.
  • homm © (24.10.07 05:52) [14]
    > [12] rts111 ©   (23.10.07 23:24)


    В таком варианте действительно пошустрее работает.

    procedure SwapChanels(BMP: TBitmap);
    type
      ADWORD = array [0..0] of DWORD;
    var
      i, j: Integer;
      Pix: DWORD;
      Line: ^ADWORD;
      Temp: byte;
    begin
      for i := 0 to BMP.Height-1 do begin
        Line := BMP.ScanLine[i];
        for j := 0 to BMP.Width-1 do begin
          Pix := Line[j];
          //Line[j] := GetBValue(Pix) + (GetGValue(Pix) shl 8) + (GetRValue(Pix) shl 16);    // 1200 mSec
          //Line[j] := byte(Pix shr 16) + (byte(Pix shr 8) shl 8) + (byte(Pix) shl 16);    // 300 mSec
          //Line[j] :=  TRGBQuad(Pix).rgbRed + (TRGBQuad(Pix).rgbGreen shl 8) + (TRGBQuad(Pix).rgbBlue shl 16);  //650 mSec
          {TRGBQuad(Line[j]).rgbBlue := TRGBQuad(Pix).rgbRed;        // 610 mSec
          TRGBQuad(Line[j]).rgbGreen := TRGBQuad(Pix).rgbGreen;
          TRGBQuad(Line[j]).rgbRed := TRGBQuad(Pix).rgbBlue;}

          with TRGBQuad(Line[j]) do begin    // 300 mSec
            Temp    := rgbRed;
            rgbRed  := rgbBlue;
            rgbBlue := Temp;
            rgbGreen  := rgbGreen;
          end;
        end;
      end;
    end;


    procedure TForm1.Button1Click(Sender: TObject);
    type
      ADWORD = array [0..0] of DWORD;
    var
      i, T: Integer;
    begin
      Image1.Picture.Bitmap := TBitmap.Create;
      Image1.Picture.Bitmap.LoadFromFile('C:\1.bmp');
      Image1.Picture.Bitmap.PixelFormat := pf32bit;

      T := GetTickCount;
      for i := 0 to 99 do
        SwapChanels(Image1.Picture.Bitmap);
      ShowMessage(IntToStr(GetTickCount-T));

    end;



    Но твоего юмора насчет одной миллисекундны я не вкурил.
  • rts111 © (24.10.07 07:44) [15]

    > homm ©   (24.10.07 05:52) [14]


    А зачем ты  rgbGreen := rgbGreen;
  • rts111 © (24.10.07 07:53) [16]

    > Но твоего юмора насчет одной миллисекундны я не вкурил.


    Да, глупо. Так я хотел сказать что такой способ быстрее.
  • homm © (24.10.07 11:28) [17]
    > [15] rts111 ©   (24.10.07 07:44)
    > А зачем ты  rgbGreen := rgbGreen;

    А за тем, что-бы убрать оптимизацию алгоритма под задачу, и абстрагироватся от задачи как можно больше.
    В принципе можешь и так написать:
           Temp    := rgbRed;
           rgbRed  := rgbGreen;
           rgbGreen := rgbBlue;
           rgbBlue  := Temp;



    Но я думаю это еше более замедлит твой вариант.
  • rts111 © (24.10.07 11:57) [18]

    > homm ©   (24.10.07 11:28) [17]



    > Но я думаю это еше более замедлит твой вариант.


    Я не понял, при чем тут ЕЩЕ БОЛЬШЕ замедлит, ведь мой вариант быстрее?
    Или у тебя на ПК не быстрее?
  • rts111 © (24.10.07 12:00) [19]

    > homm ©   (24.10.07 11:28) [17]


    А от задачи, никак невозможно абстрагироваться.
    Хочешь я приведу пример? ( только вечером, сейчас некогда )
 
Конференция "Игры" » Обратная функцыя к RGB() существует? [Delphi, Windows]
Есть новые Нет новых   [134431   +10][b:0][p:0.003]