線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1891
推到 Plurk!
推到 Facebook!

使用ScanLine做影像水平翻轉

尚未結案
kttseng2001
一般會員


發表:2
回覆:3
積分:1
註冊:2003-08-21

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-10-10 23:53:26 IP:218.164.xxx.xxx 未訂閱
小弟寫了一個影像水平翻轉的程式,可是不知道什麼地方出了問題,僅能翻轉大約三分之一的影像。以下是小弟的程式,懇請各位大人指教,謝謝。 void __fastcall TForm1::Button1Click(TObject *Sender) { Graphics::TBitmap *TheBitmap=new Graphics::TBitmap(); Graphics::TBitmap *TempBitmap=new Graphics::TBitmap(); int x, y, width, height; Byte *ptr1, *ptr2; TheBitmap->Assign(Image1->Picture->Bitmap); TempBitmap->Assign(TheBitmap); width=Image1->Picture->Width; height=Image1->Picture->Height; for(y=0 ; y < height ; y ) { ptr1=(Byte *) TempBitmap->ScanLine[y]; ptr2=(Byte *) TheBitmap->ScanLine[y]; for(x=0 ; x < width ; x ) { ptr1[x]=ptr2[width-1-x]; } } Image1->Picture->Bitmap->Assign(TempBitmap); delete TheBitmap; delete TempBitmap; //==========================================// } 發表人 - kttseng2001 於 2003/10/10 23:58:58
ayuen
一般會員


發表:19
回覆:34
積分:10
註冊:2003-07-31

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-10-11 00:11:07 IP:219.68.xxx.xxx 未訂閱
kttseng2001你好: 將for迴圈內的Width改成Width*3試試看 <>< face="Verdana, Arial, Helvetica">引言: 小弟寫了一個影像水平翻轉的程式,可是不知道什麼地方出了問題,僅能翻轉大約三分之一的影像。以下是小弟的程式,懇請各位大人指教,謝謝。 void __fastcall TForm1::Button1Click(TObject *Sender) { Graphics::TBitmap *TheBitmap=new Graphics::TBitmap(); Graphics::TBitmap *TempBitmap=new Graphics::TBitmap(); int x, y, width, height; Byte *ptr1, *ptr2; TheBitmap->Assign(Image1->Picture->Bitmap); TempBitmap->Assign(TheBitmap); width=Image1->Picture->Width; height=Image1->Picture->Height; for(y=0 ; y < height ; y ) { ptr1=(Byte *) TempBitmap->ScanLine[y]; ptr2=(Byte *) TheBitmap->ScanLine[y]; for(x=0 ; x < width ; x ) //x < width*3 改成這樣試試看 { ptr1[x]=ptr2[width-1-x]; } } Image1->Picture->Bitmap->Assign(TempBitmap); delete TheBitmap; delete TempBitmap; //==========================================//
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-10-11 00:15:39 IP:61.231.xxx.xxx 未訂閱
kttseng2001您好:   請參考下面連結作適當的修改 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=38266 謝謝您的配合
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-10-11 00:16:40 IP:61.221.xxx.xxx 未訂閱
引言: 小弟寫了一個影像水平翻轉的程式,可是不知道什麼地方出了問題,僅能翻轉大約三分之一的影像。以下是小弟的程式,懇請各位大人指教,謝謝。 void __fastcall TForm1::Button1Click(TObject *Sender) { Graphics::TBitmap *TheBitmap=new Graphics::TBitmap(); Graphics::TBitmap *TempBitmap=new Graphics::TBitmap(); int x, y, width, height; Byte *ptr1, *ptr2; TheBitmap->Assign(Image1->Picture->Bitmap); TempBitmap->Assign(TheBitmap); width=Image1->Picture->Width; height=Image1->Picture->Height; for(y=0; yScanLine[y]; ptr2=(Byte *) TheBitmap->ScanLine[y]; for(x=0; xPicture->Bitmap->Assign(TempBitmap); delete TheBitmap; delete TempBitmap; //==========================================// }
kttseng2001 你好: 試試看改成這樣子寫行不行呢?? < class="code"> Graphics::TBitmap *bmp=new Graphics::TBitmap; int x=0, y=0; Byte *ptr=NULL; bmp->Assign(Image1->Picture->Bitmap); for(y=0; yPicture->Bitmap->Height; y ) { ptr=(Byte*)bmp->ScanLine[y]; for(x=0; xPicture->Bitmap->Width/2; x ) { ptr[x]^=ptr[Image1->Picture->Bitmap->Width-1-x]; ptr[Image1->Picture->Bitmap->Width-1-x]^=ptr[x]; ptr[x]^=ptr[Image1->Picture->Bitmap->Width-1-x]; } } Image1->Picture->Bitmap->Assign(bmp); delete bmp; 備註: (1)以上範例程式碼只適用於 8 bit (256色) 的 Bitmap (2)如果你的 Bitmap 是 24 bit 的話,請自行調整修改 -- Enjoy Researching & Developing -- 發表人 - RaynorPao 於 2003/10/11 00:19:34
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
kttseng2001
一般會員


發表:2
回覆:3
積分:1
註冊:2003-08-21

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-10-11 09:40:27 IP:218.164.xxx.xxx 未訂閱
引言: kttseng2001你好: 將for迴圈內的Width改成Width*3試試看 <>< face="Verdana, Arial, Helvetica">引言: 小弟寫了一個影像水平翻轉的程式,可是不知道什麼地方出了問題,僅能翻轉大約三分之一的影像。以下是小弟的程式,懇請各位大人指教,謝謝。 void __fastcall TForm1::Button1Click(TObject *Sender) { Graphics::TBitmap *TheBitmap=new Graphics::TBitmap(); Graphics::TBitmap *TempBitmap=new Graphics::TBitmap(); int x, y, width, height; Byte *ptr1, *ptr2; TheBitmap->Assign(Image1->Picture->Bitmap); TempBitmap->Assign(TheBitmap); width=Image1->Picture->Width; height=Image1->Picture->Height; for(y=0 ; y < height ; y ) { ptr1=(Byte *) TempBitmap->ScanLine[y]; ptr2=(Byte *) TheBitmap->ScanLine[y]; for(x=0 ; x < width ; x ) //x < width*3 改成這樣試試看 { ptr1[x]=ptr2[width-1-x]; } } Image1->Picture->Bitmap->Assign(TempBitmap); delete TheBitmap; delete TempBitmap; //==========================================//
ayuen 您好: 謝謝您的指教,在修改過後,是可以將整張圖片翻轉,可是顏色卻與原來的不同了....而且...我不明白的是..為什麼要乘三倍才可以呢...整張圖的寬度應該就是>>> >再次煩請各位前輩指教,感激不盡,謝謝。< > 發表人 -
kttseng2001
一般會員


發表:2
回覆:3
積分:1
註冊:2003-08-21

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-10-11 09:49:38 IP:218.164.xxx.xxx 未訂閱
引言: kttseng2001您好: 請參考下面連結作適當的修改 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=38266 謝謝您的配合 < face="Verdana, Arial, Helvetica"> taishyang 您好: 已將原文修改完成,小弟初次發表文章,不懂規矩,還請版主大人見諒,感謝您的指教。 發表人 -
Royce520
高階會員


發表:18
回覆:157
積分:100
註冊:2002-09-13

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-10-11 19:17:27 IP:61.230.xxx.xxx 未訂閱
kttseng2001 你好,  你只翻轉了三分之一, 正是因為像素是24bits, 也就是以三個  byte 來表示一個像素的顏色, 至於Image1->Picture->Width  是整張影像的寬度...使用ScanLine 必須注意到像素是怎麼組成的  這點要非常注意... 也就是看 PixelFormat 是多少...    另外, 如果你以ScanLine 來翻轉的話, 要注意因為你使用  byte-by-byte 方式複製, 這會造成顏色錯誤...   如果以24bit 來說, 在ScanLine中的顏色擺放方式是有特定形式的  以blue->green->red 各佔一個byte, 所以你不能直接複製, 要以  整個像素為單位複製....以下是改自你的範例:    
    void __fastcall TForm1::Button1Click(TObject *Sender)
{
Graphics::TBitmap *TheBitmap=new Graphics::TBitmap();
Graphics::TBitmap *TempBitmap=new Graphics::TBitmap();
int x, y, width, height;
//Byte *ptr1, *ptr2;
typedef char (*tri)[3]; // 譬如, 16bit 像素, 這裏改2
tri ptr1, ptr2;
Image1->Picture->Bitmap->PixelFormat; // 請注意這個
TheBitmap->Assign(Image1->Picture->Bitmap);
TempBitmap->Assign(TheBitmap);
width=Image1->Picture->Width;
height=Image1->Picture->Height;
for(y=0 ; y < height ; y  )
{
ptr1=(tri) TempBitmap->ScanLine[y];
ptr2=(tri) TheBitmap->ScanLine[y];
for(x=0 ; x < width ; x  )
{
(*(ptr1 x))[0]=(*(ptr2 (width-1)-x))[0]; // blue
(*(ptr1 x))[1]=(*(ptr2 (width-1)-x))[1]; // green
(*(ptr1 x))[2]=(*(ptr2 (width-1)-x))[2]; // red
}
}
Image1->Picture->Bitmap->Assign(TempBitmap);
delete TheBitmap;
delete TempBitmap;
}    
發表人 - royce520 於 2003/10/11 19:20:50
------
不要忘記呼吸,不要忘記編程! ∩__∩
kttseng2001
一般會員


發表:2
回覆:3
積分:1
註冊:2003-08-21

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-10-11 19:56:42 IP:218.164.xxx.xxx 未訂閱
引言: kttseng2001 你好, 你只翻轉了三分之一, 正是因為像素是24bits, 也就是以三個 byte 來表示一個像素的顏色, 至於Image1->Picture->Width 是整張影像的寬度...使用ScanLine 必須注意到像素是怎麼組成的 這點要非常注意... 也就是看 PixelFormat 是多少... 另外, 如果你以ScanLine 來翻轉的話, 要注意因為你使用 byte-by-byte 方式複製, 這會造成顏色錯誤... 如果以24bit 來說, 在ScanLine中的顏色擺放方式是有特定形式的 以blue->green->red 各佔一個byte, 所以你不能直接複製, 要以 整個像素為單位複製....以下是改自你的範例:
    void __fastcall TForm1::Button1Click(TObject *Sender)
{
Graphics::TBitmap *TheBitmap=new Graphics::TBitmap();
Graphics::TBitmap *TempBitmap=new Graphics::TBitmap();
int x, y, width, height;
//Byte *ptr1, *ptr2;
typedef char (*tri)[3]; // 譬如, 16bit 像素, 這裏改2
tri ptr1, ptr2;
Image1->Picture->Bitmap->PixelFormat; // 請注意這個
TheBitmap->Assign(Image1->Picture->Bitmap);
TempBitmap->Assign(TheBitmap);
width=Image1->Picture->Width;
height=Image1->Picture->Height;
for(y=0 ; y < height ; y  )
{
ptr1=(tri) TempBitmap->ScanLine[y];
ptr2=(tri) TheBitmap->ScanLine[y];
for(x=0 ; x < width ; x  )
{
(*(ptr1 x))[0]=(*(ptr2 (width-1)-x))[0]; // blue
(*(ptr1 x))[1]=(*(ptr2 (width-1)-x))[1]; // green
(*(ptr1 x))[2]=(*(ptr2 (width-1)-x))[2]; // red
}
}
Image1->Picture->Bitmap->Assign(TempBitmap);
delete TheBitmap;
delete TempBitmap;
}    
發表人 - royce520 於 2003/10/11 19:20:50
royce520 您好: 非常感謝您如此詳細的解說,令我對於ScanLine的操作有更深入的了解,希望以後還能有此榮幸與機會向您請教,再次感謝您喔~
系統時間:2024-05-17 19:05:05
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!