|
곽성주 님이 쓰신 글 :
: 감사합니다. 나머지 델파이 코드입니다.
:
: 이건 어떻게 바뀌어야 하나요? 포인터처리가 어렵구뇨 --;
:
: ----------------------------------------------------------------------------
:
: var
: bmp1: Tbitmap;
: x, y: integer;
: p:Prgb24;
: R,G,B: Byte;
: bmp_name: string;
: begin
: bmp1:=Tbitmap.Create;
: Try
: bmp_name:='c:/testimage/angle30_24.bmp';
: bmp1.LoadFromFile(bmp_name);
: SetLength(Gray, bmp1.width, bmp1.height);
: for y:=1 to bmp1.Height-1 do
: begin
: p:=bmp1.Scanline[y];
: for x:=1 to bmp1.Width-1 do
: begin
: R:=p^.r;
: G:=p^.g;
: B:=p^.b;
: inc(p);
: Gray[x,y]:=round(R*0.3+G*0.6+B*0.1); //
: end;
: end;
: Finally
: bmp1.Free;
: end; // try
:
: end;
저는 델파이를 모릅니다.
연습삼아 한 번 컨버트해보았습니다.
논리상 오류가 있는지는 검사해보지 않았습니다.
다만, 컴파일 오류는 나지 않을 것입니다.
물귀신(?)이 생각나는군요...
TForm1 *TForm1;
BYTE *Gray, *Gray2;
struct Trgb24
{
BYTE b,g,r;
};
typedef Trgb24* Prgb24;
Graphics::TBitmap* bmp1;
int x, y;
Prgb24 p;
BYTE R,G,B;
String bmp_name;
bmp1 = new Graphics::TBitmap;
try{
bmp_name = "c:/testimage/angle30_24.bmp";
bmp1->LoadFromFile(bmp_name);
//컨버트 형식이 조금 달라졌습니다. 2차원배열로 하지 않았으니까요..
Gray = new BYTE[bmp1->Width*bmp1->Height];
int x,y;
for(y=0 ;y<bmp1->Height;++y){
p=(Prgb24)bmp1->ScanLine[y];
for(x=0 ;x<bmp1->Width;){
R = p->r;
G = p->g;
B = p->b;
++p;
*(Gray+x*bmp1->Height+y) = (BYTE)ceil(R*0.3f+G*0.6f+B*0.1f);
//델파이에서 round가 어떤 함수인지 전 모릅니다.
//C에서, floor는 전달한 수보다 크지 않은 정수 중에서 가장 큰 수를 구하고(내림)
//ceil은 전달한 수보다 작지 않은 정수 중에서 가장 작은 수를 구함(올림). math.h #include해야 합니다.
//그냥 BYTE로 캐스트하는 것은 소수점 이하를 버리는 것으로서 floor와는 조금 다릅니다.
//3가지 중 하나로 하면 되겠죠.
}//for(x
}//for(y
}__finally{
delete bmp1;
}
//어디에서인가는 delete[] Gray; 해야 합니다.
참고로, Graphics::TBitmap의 경우 PixelFormat을 검사해봐야 합니다.
만약 이게 3바이트짜리가 아니면 위의 코드는 제대로 기능을 수행하지 않을 것입니다.
|