いつもお世話になっております。澪です。
さっそく質問なのですが、TImageに読み込んだ画像の色加工の方法を教えて頂けないでしょうか?
具体的には、画像を、例えばオレンジ色にしたいです。
(色は固定です。ここでは例でオレンジ色です。)
上手く説明出来ず申し訳ありませんが、写真に色セロハンをかぶせるような感じです。
また、TrackBarかEditでその色の濃さを指定出来ないでしょうか。
質問ばかりで申し訳ありませんが、宜しくお願い致しますm(_ _)m
ここを見てください。
http://junki.main.jp/delphigr/046AlphaBlend.htm
オレンジ色に塗った Bitmap を JAlphaBlend() で元画像に重ね描きします。
濃さも設定できます。
色が褪せた様に残すのならjunkiさんの方法で。
セピア写真みたいに白黒に色を付けるなら、
RGBからY(輝度)だけを取り出し、UV(色成分)を好きな固定値にして、
YUV->RGB変換がオーソドックスです。
ビデオカメラなんかの「セピア効果」はほぼこの方式です。
なお、UVを固定値で無く、元の値と固定値とのブレンドにすれば元の色がやや残ります。
サンプルコード出せればよいのですがちょっと時間が・・・
見た目だけなら、以下でも出来ます(^▽^;)
ShapeのBrushのColorをオレンジ色に。
ShapeのPenのModeをpmMaskに。
このShapeをTImageの上に置く。
(見た目だけです・・・)
長いですが・・・
image1・2 と trackbar1・2 を置いてください。
----------------------------------------------------
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Math, StdCtrls, ExtCtrls, ComCtrls;
type
TRGBTripleArray = array[0 .. High(Integer) div 3 - 1] of RGBTRIPLE;
PRGBTripleArray = ^TRGBTripleArray; //配列型のポインタ
TForm1 = class(TForm)
Image1: TImage;
Image2: TImage;
TrackBar1: TTrackBar;
TrackBar2: TTrackBar;
procedure FormCreate(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
private
{ Private 宣言 }
public
function Med3(a : integer ; b : integer; c : integer) : integer;
procedure getRGB( P :PRGBTripleArray; x: integer;var R :Short; var G :Short; var B :Short);
procedure setRGB( P :PRGBTripleArray; x: integer; R ,G, B :Short);
procedure SetColoFilter();
procedure RGB2YUV709( R,G,B :Short ;var Y :Short; var U :Short; var V :Short);
procedure YUV2RGB709( Y,U,V :Short ;var R :Short; var G :Short; var B :Short);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.getRGB( P :PRGBTripleArray; x: integer;var R :Short; var G :Short; var B :Short);
begin
R := P[x].rgbtRed;
G := P[x].rgbtGreen;
B := P[x].rgbtBlue;
end;
procedure TForm1.setRGB( P :PRGBTripleArray; x: integer; R ,G, B :Short);
begin
P[x].rgbtRed := R ;
P[x].rgbtGreen:= G ;
P[x].rgbtBlue := B ;
end;
procedure TForm1.TrackBar1Change(Sender: TObject);
begin
SetColoFilter();
end;
procedure TForm1.RGB2YUV709( R,G,B :Short ;var Y :Short; var U :Short; var V :Short);
begin
Y := Med3( 0,255,( 183*R +614*G + 62*B) div 1000);
V := Med3(-128,127,(-101*R -339*G +439*B) div 1000);
U := Med3(-128,127,( 439*R -399*G + 40*B) div 1000);
end;
procedure TForm1.YUV2RGB709( Y,U,V :Short ;var R :Short; var G :Short; var B :Short);
begin
Y := Y -16;
R := Med3( 0,255,(1164*Y +1792*V) div 1000);
G := Med3( 0,255,(1164*Y -213*U - 534*V) div 1000);
B := Med3( 0,255,(1167*Y+2113*U ) div 1000);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Image1.Picture.LoadFromFile('虫.bmp'); //適当にbmpのファイルをアサインすること
Image2.Picture.LoadFromFile('虫.bmp'); //適当にbmpのファイルをアサインすること
TrackBar1.Max := 128;
TrackBar2.Max := 128;
TrackBar1.Min := -128;
TrackBar2.Min := -128;
TrackBar1.Frequency := 16;
TrackBar2.Frequency := 16;
end;
function TForm1.Med3(a : integer ; b : integer; c : integer) : integer;
begin
if (a>b) then
begin
if(c>a) then result := a
else result := Max(b,c);
end
else
begin
if(c>b) then result := b
else result := Max(a,c);
end
end;
procedure TForm1.SetColoFilter();
var
Ps0,Ps1: PRGBTripleArray;
BMP : TBitMap;
x,y :Integer;
R0,G0,B0 :Short;
R1,G1,B1 :Short;
Y0,U0,V0 :Short;
U1,V1 :Short;
begin
BMP := TBitMap.Create;
BMP.PixelFormat := pf24bit;
BMP.Width := Form1.Image1.Picture.Bitmap.Width ;
BMP.Height := Form1.Image1.Picture.Bitmap.Height;
//処理
for y := 0 to Form1.Image1.Picture.Bitmap.Height-1 do
begin
Ps0 := Form1.Image1.Picture.Bitmap.ScanLine[y];
Ps1 := BMP.ScanLine[y];
for x := 0 to Form1.Image1.Picture.Bitmap.Width -1 do
begin
getRGB( Ps0, x, R0,G0,B0);
RGB2YUV709(R0,G0,B0, Y0,U0,V0);
U1 := TrackBar1.Position;
V1 := TrackBar2.Position;
YUV2RGB709(Y0,U1,V1,R1,G1,B1);
setRGB(Ps1, x ,R1,G1,B1);
end;
end;
Image2.Picture.Bitmap.Assign(BMP);
Ps1 := BMP.ScanLine[0];
getRGB(Ps1, 0 , R0,G0,B0);
BMP.free;
end;
end.
皆さん、回答ありがとうございます。
とりあえず全部を試そうと思ったんですけど・・・
junkiの方法なんですけど、PingImageが落とせずに試すことが出来ません。
http://pngdelphi.sourceforge.net/
↑の左上のdownloadってどこであってます??
いつまでたってもdownloadが始まらなくて。。。
一時的にセキュリティ切ってみたら?
セキュリティってインターネットオプションのセキュリティとかでOKですか?
一応一番低いのにしてもの駄目でしたorz
セキュリティ系のソフトも入れてないし。。
ん〜何が悪いのでしょう(;^_^A
どこまでいけるの?
http://prdownloads.sourceforge.net/pngdelphi/pngimage.zip?use_mirror=jaist
http://jaist.dl.sourceforge.net/sourceforge/pngdelphi/pngimage.zip
> junkiの方法なんですけど、PingImageが落とせずに試すことが出来ません。
今回の問題には、Png 画像を使う事は特に本質とは関係ありません。
jpeg 画像を使った例を示します。これなら、Delphi だけでできます。
uses
Jpeg;
function JAlphaBlend(dst: TCanvas; dstX, dstY: integer;
src: TBitmap; alpha: single):Boolean;
var
bf: TBlendFunction;
begin
bf.BlendOp := AC_SRC_OVER;
bf.BlendFlags := 0;
bf.SourceConstantAlpha := Round(alpha*255/100);
bf.AlphaFormat := 0;
result := Windows.AlphaBlend(dst.Handle, dstX, dstY, src.Width,
src.Height,src.Canvas.Handle, 0, 0, src.Width, src.Height, bf);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
bmp, orange: TBitmap;
jpg: TJpegImage;
begin
jpg := TJpegImage.Create;
bmp := TBitmap.Create;
orange := TBitmap.Create;
try
jpg.LoadFromFile('c:\test.jpg'); // 適当な jpg 画像。
bmp.Assign(jpg); // bmp に写し取る
orange.Width := bmp.Width;
orange.Height := bmp.Height;
orange.PixelFormat := pf24bit;
orange.Canvas.Brush.Color := RGB(255, 111, 15); //適当なオレンジ色
orange.Canvas.Pen.Color := RGB(255, 111, 15);
orange.Canvas.FillRect(Rect(0, 0, orange.Width, orange.Height));
Canvas.Draw(5, 5, bmp);
JAlphaBlend(bmp.Canvas, 0, 0, orange, 30); // 30%オレンジ色を重ねる
Canvas.Draw(5, bmp.Height + 10, bmp);
finally
jpg.Free;
bmp.Free;
orange.Free;
end;
end;
junkiさん、わざわざ私の為にありがとうございますm(_ _)m
それに、呼び捨てにしてしまって申し訳ありません。。。orz
おかげで無事出来ましたっ!!
それに、皆さん、アドバイスありがとうございます。
具体的にさんのおかげで、落とすこともできました。
本当にありがとうございましたっ!!
ツイート | ![]() |