C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[55982] Re:Re:TImage 회전 함수 질문
ant [] 2266 읽음    2009-02-03 22:08
답변 감사합니다.

몇가지 질문할 게 더 있어서 질문드립니다.. ㅠㅠ
일단 C++로 다 옮기는데는 성공했습니다만 회전한 이미지가 아얘 나타나질 않습니다.

일단
[1] SetColor32에서 맨 마지막의 Move가 어떤 작업을 수행하는 건지 알고 싶습니다.
(제 나름대로 해석해서 코딩했습니다만 결국 *pd에 대해서 나온 결과를 쓰질 않는 것 같습니다..)
[2] (...) div 2 는 (...)를 2로 나눈다는 뜻(즉, (...)/2와 같은 뜻)인가요?
[3] 델파이에서 High(x)가 x의 할당 개수를 의미하는게 맞나요?? (#define으로 정의해 버렸습니다만...)
[4] 이 밖에 함수 선언이 올바르게 되었는지 알고 싶습니다.. 어떤 거는 function이고 어떤거는 procedure이던데 procedure가 return(즉 result를 적는 코드)이 없어 그냥 void로 처리해 버렸습니다. 맞는지 확인해 주시면 감사하겠습니다.. ㅠㅠ

아래는 변환해 본 소스 코드입니다.. 감사합니다.

ps. 157번째 줄부터 제대로 안나오네요... 157번쨰 줄~FormDestroy 부분은 여기다 올리겠습니다...

        for (iy = dstR.Top; iy<dstR.Bottom; iy++) {
                for (ix = dstR.Left; ix<dstR.Right; ix++) {
                        pt = Point(ix, iy);
                        pt = RotatePoint(-sn, cs, Xc, Yc, pt);
                        if (!PtInRct(pt, srcR)) continue;
                        SetColor32(dst, ix+Xofs, iy+Yofs, GetColor32(src, pt.x, pt.y));
                }
        }
}


void __fastcall TForm1::FormCreate(TObject *Sender)
{
        srcbmp = new Graphics::TBitmap;
        srcbmp->PixelFormat = pf32bit;
        srcbmp->Width = 300;
        srcbmp->Height = 300;

        srcbmp->LoadFromFile("C:\\Test.bmp");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
        delete srcbmp;       
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------

#include 
#include 
#pragma hdrstop

#include "Unit1.h"

#define pi 3.141592
#define High(x) ( sizeof((x)) / sizeof((x)[0]) ) 
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
TRGBQuad __fastcall GetColor32(Graphics::TBitmap *bmp,int x,int y)
{
        TRGBQuad * ps;
        ps = (TRGBQuad *)bmp->ScanLine[y];
        ps=ps+x;
        return *ps;
}
void SetColor32(Graphics::TBitmap *bmp, int x, int y, TColor color)
{
        TRGBQuad c;
        COLORREF k;
        TRGBQuad * pd; // PRGBQuad

        k = ColorToRGB(color);
        c.rgbBlue = GetBValue(k);
        c.rgbGreen = GetGValue(k);
        c.rgbRed = GetRValue(k);
        c.rgbReserved = 0;
        pd = (TRGBQuad *)bmp->ScanLine[y];
        pd = pd+x;
        *pd = c;  //Move(c,pd^,SizeOf(TRGBQuad));
}
void SetColor32(Graphics::TBitmap *bmp, int x, int y, const TRGBQuad rgbq)
{
        TRGBQuad * pd;

        pd = (TRGBQuad *)bmp->ScanLine[y];
        pd = pd + x;
        *pd = rgbq; // Move(rgbq,pd^,SizeOf(TRGBQuad));
}
TRect GetBoundRect(const TPoint pts[])
{
        int i, Xmax, Xmin, Ymax, Ymin;

        Xmax = pts[0].x; Xmin = pts[0].x;
        Ymax = pts[0].y; Ymin = pts[0].y;

        for (i=1; i<=High(pts); i++) {
                if (pts[i].x > Xmax) Xmax = pts[i].x;
                if (pts[i].x < Xmin) Xmin = pts[i].x;
                if (pts[i].y > Ymax) Ymax = pts[i].y;
                if (pts[i].y < Ymin) Ymin = pts[i].y;
        }
        return Rect(Xmin, Ymin, Xmax, Ymax);
}

TPoint RotatePoint(const double sn, const double cs, int Xc, int Yc, TPoint pt)
{
        TPoint tmppt;
        tmppt.x = (Xc+cs*(pt.x-Xc)-sn*(pt.y-Yc))+0.5;
        tmppt.y = (Yc+sn*(pt.x-Xc)+cs*(pt.y-Yc))+0.5;

        return tmppt;
}
TPoint RotatePoint(double deg, int Xc, int Yc, TPoint pt)
{
        double sn, cs;

        sn = sin(pi*deg/180);
        cs = cos(pi*deg/180);

        TPoint tmppt;
        tmppt.x = (Xc+cs*(pt.x-Xc)-sn*(pt.y-Yc))+0.5;
        tmppt.y = (Yc+sn*(pt.x-Xc)+cs*(pt.y-Yc))+0.5;

        return tmppt;
}

void OffsetPoints(TPoint pt[], int dx, int dy)
{
        int i;

        for (i=0; i<=High(pt); i++) {
                pt[i] = Point(pt[i].x+dx, pt[i].y+dy);
        }
}

bool PtInRct(const TPoint pt, const TRect r)
{
        return ((pt.x >= r.Left) && (pt.x < r.Right) &&
                (pt.y >= r.Top) && (pt.y < r.Bottom));
}
void RotatePoints(double deg, TPoint pts[])
{
        int i, Xc, Yc;
        TRect r;
        Double sn, cs;

        r = GetBoundRect(pts);

        Xc = (r.Left + r.Right) / 2;
        Yc = (r.Top + r.Bottom) / 2;

        sn = sin(pi*deg/180);
        cs = cos(pi*deg/180);

        for (i=0; i<=High(pts); i++) {
                pts[i] = RotatePoint(sn, cs, Xc, Yc, pts[i]);
        }
}
//--------------------------------------------------------
void RotateBMP32(double deg, Graphics::TBitmap *src, Graphics::TBitmap *dst, TColor bkColor)
{
        TRect srcR, dstR;
        TPoint pts[3];
        int Xofs, Yofs, w, h;
        int ix, iy, Xc, Yc;
        TPoint pt;
        double sn, cs;

        srcR = Rect(0, 0, src->Width, src->Height);
        Xc = src->Width / 2;
        Yc = src->Height / 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; iyPixelFormat = pf32bit;
        srcbmp->Width = 300;
        srcbmp->Height = 300;

        srcbmp->LoadFromFile("C:\\Test.bmp");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
        delete srcbmp;        
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
        Graphics::TBitmap * bmp;

        bmp = new Graphics::TBitmap;

        Canvas->Draw(5, 5, srcbmp);
        RotateBMP32(-35, srcbmp, bmp, clRed);
        bmp->TransparentColor = clRed;
        bmp->Transparent = true;
        Canvas->Draw(300, 300, bmp);

        delete bmp;
}
//---------------------------------------------------------------------------






장성호 님이 쓰신 글 :
: Object-Pascal의  꺽쇄(^)는  C++의 포인터(*)와 같습니다.
:
:
: function GetColor32(bmp:TBitmap; x,y:integer):TRGBQuad; 
: var 
:   ps:PRGBQuad;  //TRGBQuad * 형 ps선언 
: begin 
:   ps := bmp.Scanline[y];  //y번째 줄의 시작 포인터 가져옴
:   Inc(ps,x);                       //x만큼 포인터를 이동
:   Move(ps^,result,SizeOf(TRGBQuad)); // 포인터의 값을 result에 복사
: end;
: //Object-Pascal의 function에서는  Result가 return값이 됩니다.
: 

:
: 위 함수를 C++로 바꾸면
:
: TRGBQuad __fastcall GetColor32(Graphics::TBitmap *bmp,int x,int y)
: {
:     TRGBQuad * ps;
:     ps = (TRGBQuad *)bmp->ScanLine[y]; 
:     ps=ps+x;
:     return *ps;
: }
: 

: 뭐 대충 위와 같이 하면 될것 같습니다.
:
:
: 그리고 pascal에서 overload 라고 되어있는것은
: C++에서는 함수 overload를 기본 지원하는것이니 빼도 됩니다.
:
: override란 함수이름은 같구  파라메터가 다른경우에 해당하는것입니다.
:
: 그리고 image 회전을 할때
: 기본적으로 Graphic32 에서도 90도의 배수만 지원하는걸로 알고 있습니다.
:
: 다른 각도는 직접 구현하셔야 합니다.
: 정확히 대칭되는 pixcel이 없기때문에 보간법을 이용하여 구현하곤 합니다.
:
: 님께서 찾은 delphi코드가 아무각도에서는 이미지가 회전되는 코드입니다.
:
: 델마당에 조무영님의 비dx강좌링크에 delphi로 된 image회전이 나와있습니다.
: http://www.delmadang.com/community/bbs_view.asp?bbsNo=29&bbsCat=0&st=S&keyword=%uBE44DX&indx=198680&keyword1=비DX&keyword2=&page=2
:
:
: 그럼...
:
: 위 함수는
: ant 님이 쓰신 글 :
: : 안녕하세요.
: : 다름아니라 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.
: : 

+ -

관련 글 리스트
55971 TImage 회전 함수 질문 ant 1894 2009/02/03
55994     Graphics32 임의 각도 회전 이정구 1457 2009/02/04
55999         Re:Graphics32 임의 각도 회전 ant 2315 2009/02/04
55973     Re:TImage 회전 함수 질문 장성호 2736 2009/02/03
55982         Re:Re:TImage 회전 함수 질문 ant 2266 2009/02/03
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.