お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"スクリーン、乗算、オーバーレイ"



 みなさん、こんにちは。


<乗算>>

■概要
 PhotoShopのレイヤー属性、塗りつぶし属性のうち、乗算、スクリーン、オー
バーレイのサンプルです。

「結果色」={基本色、合成色}
 として、
スクリーン:基本色を、合成色によって明るくする。
乗算:基本色を、合成色によって暗くする。
オーバーレイ:基本色の明度によって、合成色による効果を変化させて適用

 のように動作します。

 Form1 に Image1,Image2、Button1,2,3 を適当に配置し、テスト用のビットマ
ップを適宜用意して実行して下さい。

■サンプルコード

procedure TForm1.Button1Click(Sender: TObject);
begin
  bmpOrg := TBitmap.Create;
  bmpSrc := TBitmap.Create;

  bmpOrg.LoadFromFile('c:\temp\test1.bmp');
  bmpSrc.LoadFromFile('c:\temp\test2.bmp');

  Image1.Canvas.Draw(0,0,bmpOrg);
  Image2.Canvas.Draw(0,0,bmpSrc);

  bmpOrg.Free;
  bmpSrc.Free;

end;


procedure TForm1.Button2Click(Sender: TObject);
var
  rectDst, rectSrc: TRect;
  x, y: Integer;
  prgbDst, prgbSrc: PRGBQuad;
begin

  rectSrc := RECT(0, 0, Image1.Width, Image1.Height);
  rectDst := RECT(0, 0, Image2.Width, Image2.Height);

  Image1.Picture.Bitmap.PixelFormat := pf32Bit;
  Image2.Picture.Bitmap.PixelFormat := pf32Bit;

  for y := rectSrc.Top to rectSrc.Bottom - 1 do
    begin
      prgbDst := Image1.Picture.Bitmap.ScanLine[y];
      prgbSrc := Image2.Picture.Bitmap.ScanLine[y];

      for x := rectSrc.Left to rectSrc.Right - 1 do
      begin
 //スクリーン
 //基本色200、合成色128とすると
 //200→227
 //  200+(255-200)*128/255
 //  (255*200+255*128-200*128)/255

        prgbDst^.rgbRed   :=
            (255*prgbDst^.rgbRed + 255*prgbSrc^.rgbRed -
             prgbDst^.rgbRed*prgbSrc^.rgbRed) div 255;
        prgbDst^.rgbGreen   :=
            (255*prgbDst^.rgbGreen + 255*prgbSrc^.rgbGreen -
             prgbDst^.rgbGreen*prgbSrc^.rgbGreen) div 255;
        prgbDst^.rgbBlue   :=
            (255*prgbDst^.rgbBlue + 255*prgbSrc^.rgbBlue -
             prgbDst^.rgbBlue*prgbSrc^.rgbBlue) div 255;
        Inc(prgbDst);
        Inc(prgbSrc);
      end;
    end;
  end;

procedure TForm1.Button3Click(Sender: TObject);
var
  rectDst, rectSrc: TRect;
  x, y: Integer;
  prgbDst, prgbSrc: PRGBQuad;
begin

  rectSrc := RECT(0, 0, Image1.Width, Image1.Height);
  rectDst := RECT(0, 0, Image2.Width, Image2.Height);

  Image1.Picture.Bitmap.PixelFormat := pf32Bit;
  Image2.Picture.Bitmap.PixelFormat := pf32Bit;

  for y := rectSrc.Top to rectSrc.Bottom - 1 do
    begin
      prgbDst := Image1.Picture.Bitmap.ScanLine[y];
      prgbSrc := Image2.Picture.Bitmap.ScanLine[y];

      for x := rectSrc.Left to rectSrc.Right - 1 do
      begin
 //乗算
 //基本色200,合成色0 とすると(黒)
 //200→0.
 //  200-200*100%
 //  200-200*(255-0)/255
 //    (255*200-255*200+200*0)/255
 //    200*0/255

        prgbDst^.rgbRed   :=
            (prgbDst^.rgbRed*prgbSrc^.rgbRed) div 255;
        prgbDst^.rgbGreen   :=
            (prgbDst^.rgbGreen*prgbSrc^.rgbGreen) div 255;
        prgbDst^.rgbBlue   :=
            (prgbDst^.rgbBlue*prgbSrc^.rgbBlue) div 255;
        Inc(prgbDst);
        Inc(prgbSrc);
      end;
    end;
end;

procedure TForm1.Button4Click(Sender: TObject);
var
  rectDst, rectSrc: TRect;
  x, y: Integer;
  prgbDst, prgbSrc: PRGBQuad;
begin

  rectSrc := RECT(0, 0, Image1.Width, Image1.Height);
  rectDst := RECT(0, 0, Image2.Width, Image2.Height);

  Image1.Picture.Bitmap.PixelFormat := pf32Bit;
  Image2.Picture.Bitmap.PixelFormat := pf32Bit;

  for y := rectSrc.Top to rectSrc.Bottom - 1 do
    begin
      prgbDst := Image1.Picture.Bitmap.ScanLine[y];
      prgbSrc := Image2.Picture.Bitmap.ScanLine[y];

      for x := rectSrc.Left to rectSrc.Right - 1 do
      begin
 //オーバーレイ
 //基本色>128
 // 結果色=基本色+(255-基本色)*(合成色-128)/128
 //基本色<=128
 // 結果色=基本色+基本色*(合成色-128)/128

        if (prgbDst^.rgbRed > 128) then
            prgbDst^.rgbRed   :=
            prgbDst^.rgbRed + (255 - prgbDst^.rgbRed)*(prgbSrc^.rgbRed - 
128) div 128
          else
            prgbDst^.rgbRed   :=
            prgbDst^.rgbRed + prgbDst^.rgbRed*(prgbSrc^.rgbRed - 128) 
div 128;
        if (prgbDst^.rgbGreen > 128) then
            prgbDst^.rgbGreen   :=
            prgbDst^.rgbGreen + (255 - 
prgbDst^.rgbGreen)*(prgbSrc^.rgbGreen - 128) div 128
          else
            prgbDst^.rgbGreen   :=
            prgbDst^.rgbGreen + prgbDst^.rgbGreen*(prgbSrc^.rgbGreen - 
128) div 128;
        if (prgbDst^.rgbBlue > 128) then
            prgbDst^.rgbBlue   :=
            prgbDst^.rgbBlue + (255 - 
prgbDst^.rgbBlue)*(prgbSrc^.rgbBlue - 128) div 128
          else
            prgbDst^.rgbBlue   :=
            prgbDst^.rgbBlue + prgbDst^.rgbBlue*(prgbSrc^.rgbBlue - 128) 
div 128;
        Inc(prgbDst);
        Inc(prgbSrc);
      end;
    end;
end;

http://www.st.rim.or.jp/~toyozou
                      99/08/18(水) 20:23 とよぞう(PXW07530)

Original document by とよぞう        氏 ID:(PXW07530)


ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum