안녕하세요.
다름아니라 TImage를 회전하려고 찾다가 아래 소스를 발견했는데요..
pascal이라서 c++로 옮기려다 난해한 부분들이 있어서 질문 드립니다.
[1] 아래에서 예를들어
function GetColor32(bmp:TBitmap; x,y:integer):TRGBQuad;
var
ps:PRGBQuad;
begin
ps := bmp.Scanline[y];
Inc(ps,x);
Move(ps^,result,SizeOf(TRGBQuad));
end;
이게 return값이 뭔지, ps^에서 ^가 가리키는게 뭔지 등등... 잘 모르겠습니다 ㅠㅠ;;
C++이랑 비슷한 것 같으면서도 고치기가 많이 힘드네요.. ㅠㅠ
그리고
[2] 어떤 함수는 옆에 overload; 이렇게 되어 있는데 이것도 c++로 어떻게 바꿔야 하는지 등등
자세히 알려주시면 감사하겠습니다.. ㅠㅠ
ps. Graphic32는 이미지 위의 이미지가 투명 처리가 안되더군요... 게다가 저는 rotate를 90도, 180도, 270도 등 뿐만 아니라 특정 각도까지 구현해야 되는 상황인데, Graphic32에는 Rotate90, Rotate180, Rotate270밖에 없었습니다...
출처는
http://blog.livedoor.jp/junki560/archives/19004116.html 이구요
아래는 전체 소스코드 입니다...
unit Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
srcbmp:TBitmap;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
Jpeg;
function GetColor32(bmp:TBitmap; x,y:integer):TRGBQuad;
var
ps:PRGBQuad;
begin
ps := bmp.Scanline[y];
Inc(ps,x);
Move(ps^,result,SizeOf(TRGBQuad));
end;
procedure SetColor32(bmp:TBitmap; x,y:integer; color:TColor);overload;
var
c:TRGBQuad;
k:COLORREF;
pd:PRGBQuad;
begin
k := ColorToRGB(color);
c.rgbBlue := GetBValue(k);
c.rgbGreen := GetGValue(k);
c.rgbRed := GetRValue(k);
c.rgbReserved := 0;
pd := bmp.Scanline[y];
Inc(pd,x);
Move(c,pd^,SizeOf(TRGBQuad));
end;
procedure SetColor32(bmp:TBitmap; x,y:integer;const rgbq:TRGBQuad);overload;
var
pd:PRGBQuad;
begin
pd := bmp.Scanline[y];
Inc(pd,x);
Move(rgbq,pd^,SizeOf(TRGBQuad));
end;
function GetBoundRect(const pts:array of TPoint):TRect;
var
i,Xmax,Xmin,Ymax,Ymin:integer;
begin
Xmax := pts[0].X; Xmin := pts[0].X;
Ymax := pts[0].Y; Ymin := pts[0].Y;
for i := 1 to High(pts) do
begin
if pts[i].X > Xmax then Xmax := pts[i].X;
if pts[i].X < Xmin then Xmin := pts[i].X;
if pts[i].Y > Ymax then Ymax := pts[i].Y;
if pts[i].Y < Ymin then Ymin := pts[i].Y;
end;
result := Rect(Xmin,Ymin,Xmax,Ymax);
end;
function RotatePoint(const sn,cs:Double;Xc,Yc:integer;pt:TPoint):TPoint;overload;
begin
result.X := Round(Xc+cs*(pt.X-Xc)-sn*(pt.Y-Yc));
result.Y := Round(Yc+sn*(pt.X-Xc)+cs*(pt.Y-Yc));
end;
function RotatePoint(deg:Double;Xc,Yc:integer;pt:TPoint):TPoint;overload;
var
sn,cs:Double;
begin
sn := sin(pi*deg/180);
cs := cos(pi*deg/180);
result.X := Round(Xc+cs*(pt.X-Xc)-sn*(pt.Y-Yc));
result.Y := Round(Yc+sn*(pt.X-Xc)+cs*(pt.Y-Yc));
end;
procedure OffsetPoints(var pt:array of TPoint;dx,dy:integer);
var
i:integer;
begin
for i := 0 to High(pt) do
pt[i] := Point(pt[i].X+dx,pt[i].Y+dy)
end;
function PtInRct(const pt:TPoint; const r:TRect):Boolean;
begin
result := (pt.X>=r.Left) and (pt.X<r.Right) and
(pt.Y>=r.Top) and (pt.Y<r.Bottom);
end;
procedure RotatePoints(deg:Double ;var pts:array of TPoint);
var
i,Xc,Yc:integer;
r:TRect;
sn,cs:Double;
begin
r := GetBoundRect(pts);
Xc := (r.Left+r.Right) div 2;
Yc := (r.Top+r.Bottom) div 2;
sn := sin(pi*deg/180);
cs := cos(pi*deg/180);
for i := 0 to High(pts) do
pts[i] := RotatePoint(sn,cs,Xc,Yc,pts[i]);
end;
//--------------------------------------------------------
procedure RotateBMP32(deg:Double; src,dst:TBitmap; bkColor:TColor);
var
srcR,dstR:TRect;
pts:array[0..3] of TPoint;
Xofs,Yofs,w,h:integer;
ix,iy,Xc,Yc:integer;
pt:TPoint;
sn,cs:Double;
begin
srcR := Rect(0,0,src.Width,src.Height);
Xc := src.Width div 2;
Yc := src.Height div 2;
pts[0] := Point(0,0);
pts[1] := Point(src.Width,0);
pts[2] := Point(src.Width,src.Height);
pts[3] := Point(0,src.Height);
RotatePoints(deg,pts);
dstR := GetBoundRect(pts);
Xofs := -dstR.Left;
Yofs := -dstR.Top;
w := dstR.Right-dstR.Left;
h := dstR.Bottom-dstR.Top;
dst.PixelFormat := pf32bit;
dst.Width := w;
dst.Height := h;
dst.Canvas.Brush.Color := bkColor;
dst.Canvas.FillRect(Rect(0,0,w,h));
sn := sin(pi*deg/180);
cs := cos(pi*deg/180);
for iy := dstR.Top to dstR.Bottom-1 do
for ix := dstR.Left to dstR.Right-1 do
begin
pt := Point(ix,iy);
pt := RotatePoint(-sn,cs,Xc,Yc,pt);
if not PtInRct(pt,srcR) then continue;
SetColor32(dst,ix+Xofs,iy+Yofs,GetColor32(src,pt.X,pt.Y));
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
jpg:TJpegImage;
begin
srcbmp := TBitmap.Create;
jpg := TJpegImage.Create;
try
jpg.LoadFromFile(ExtractFilePath(ParamStr(0))+'Test.jpg');
srcbmp.PixelFormat := pf32bit;
srcbmp.Width := jpg.Width;
srcbmp.Height := jpg.Height;
srcbmp.Canvas.Draw(0,0,jpg);
finally
jpg.Free;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
srcbmp.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
bmp:TBitmap;
begin
bmp := TBitmap.Create;
try
Canvas.Draw(5,5,srcbmp);
RotateBMP32(-35,srcbmp,bmp,clRed);
bmp.TransparentColor := clRed;
bmp.Transparent := true;
Canvas.Draw(5,srcbmp.Height+10,bmp);
finally
bmp.Free;
end;
end;
end.