如何用scanline存放改變後的二維陣列(我是新手) |
尚未結案
|
kmp
一般會員 發表:17 回覆:51 積分:13 註冊:2004-07-24 發送簡訊給我 |
不好意思,我是新手,想請問如同前說過不是內插法和單純的縮小放大,利用
(a[0][0] a[0][1] a[1][0] a[1][1])/4就是把圖四點的pixels值相加後除四
而得到新的值,然後寫回去,使用scanline存取兩個array,一是原圖,一是縮小後的o 以下是我的部份程式,有問題在行間,請看: int *imagedata=new int [Width*Height];
int x=0;
for( int j=0 ; j < Height ; j ) // ---> 用來變動列
{ //;dexed access to each line of pixels
ptr1=(Byte*)TheBitmap->ScanLine[j]; // ---> 把一整列的pixel掃進來
ptr2=(Byte*)TempBitmap->ScanLine[j];
for(int i=0 ; i < Width ; i ) // ---> 用來變換行
{
imagedata[i j*Width]=ptr1[x];
// 把每列的每個pixel塞到imageData這個array,利用 i j*width來變換位置 *ptr2=(*(ptr1 x) *(ptr1 x 1) *(ptr1 x Width) *(ptr1 x Width 1))/4 ;
// 我有問題在這,bmp->array->處理後array->bmp
// ^^^^^^^^^^^^^^這裡有問題,我不會,請教o謝謝
}
|
TheMoon
中階會員 發表:17 回覆:95 積分:67 註冊:2002-06-05 發送簡訊給我 |
程式中用到x的地方要改成i,如下: for( int j=0 ; j < Height ; j ) // ---> 用來變動列
{
ptr1=(Byte*)TheBitmap->ScanLine[j]; // ---> 把一整列的pixel掃進來
ptr2=(Byte*)TempBitmap->ScanLine[j];
for(int i=0 ; i < Width ; i ) // ---> 用來變換行
{
imagedata[i j*Width]=ptr1[x];
//x改成i *ptr2=(*(ptr1 x) *(ptr1 x 1) *(ptr1 x Width) *(ptr1 x Width 1))/4 ;
//x改成i
}
} ----
另外你的問題是否是要將一個圖縮小成原來的1/4倍,
縮小的圖是取原圖中相鄰四點之平均值而得?
如果是這樣的話,提供一個作法:
(假設原圖為256灰階影像,Width=256,Height=256)
(縮小後之圖為256灰階影像,Width=128,Height=128) unsigned char temp[128][128]; //暫存計算好的pixel值
Graphics::TBitmap *A = new Graphics::TBitmap(); //原圖
Graphics::TBitmap *B = new Graphics::TBitmap(); //縮圖
Byte *ptr1,*ptr2;
int i,j; for(j=0;j < A->Height;j=j 2)
{
ptr1=(Byte *)A->ScanLine[j];
ptr2=(Byte *)A->ScanLine[j 1];
for(i=0;i < A->Width;i=i 2)
{
temp[(int)j/2][(int)i/2]=(int)((ptr1[i] ptr1[i 1] ptr2[i] ptr2[i 1])/4);
}
} B->PixelFormat=pf8bit;
B->Height=128;
B->Width=128;
B->Palette=CreatePalette(&GrayPalette.lPal);
for(j=0;j < B->Height;j )
{
ptr1=(Byte *)B->ScanLine[j];
for(i=0;i < B->Width;i ) ptr1[i]=temp[j][i];
} 發表人 - TheMoon 於 2004/07/27 17:20:58〈〈〈 發表人 - TheMoon 於 2004/07/27 17:34:16
|
kmp
一般會員 發表:17 回覆:51 積分:13 註冊:2004-07-24 發送簡訊給我 |
我不太有寫程式經驗,想問一個可能很簡單基本的問題,如下在//中:
引言: 程式中用到x的地方要改成i,如下: for( int j=0 ; j < Height ; j ) // ---> 用來變動列 { ptr1=(Byte*)TheBitmap->ScanLine[j]; // ---> 把一整列的pixel掃進來 ptr2=(Byte*)TempBitmap->ScanLine[j]; for(int i=0 ; i < Width ; i ) // ---> 用來變換行 { imagedata[i j*Width]=ptr1[x]; //x改成i //請問這裡的i是因為在i 回圈裡嗎?可是,它的i和前者的i我覺好像代表不 //同的意義,一是二為裡的第幾行,一個是二維變一維裡,代表第幾個o *ptr2=(*(ptr1 x) *(ptr1 x 1) *(ptr1 x Width) *(ptr1 x Width 1))/4 ; //請問這程式只有x改成i的問題嗎?我這行,是否無法達成我想作的目地, //因為我用指標,沒有存取array,換句話說,我可以得到那要縮小scanline //的圖嗎? 其實是改成bmp1->array1->deal with->array2->bmp2, //其中bmp2是原本bmp的長寬各縮一半,前述縮法,這樣較好,可是 //若我想不呼叫 bmp2array 和array2bmp ,這樣用scanline可達成嗎? // 謝謝 ,若不行,可以提示怎改較好 //>>< face="Verdana, Arial, Helvetica">< >< > |
TheMoon
中階會員 發表:17 回覆:95 積分:67 註冊:2002-06-05 發送簡訊給我 |
|
brook
資深會員 發表:57 回覆:323 積分:371 註冊:2002-07-12 發送簡訊給我 |
Graphics::TBitmap *A; Graphics::TBitmap *B; //圖形來源自己處理 Byte *ptr1,*ptr2,*ptr3; //設寬高 B->Height = A->Height/2; B->Width = A->Width/2; //轉成pf8bit A->PixelFormat = pf8bit; B->PixelFormat = pf8bit; int i,j; for(j=0;j |
kmp
一般會員 發表:17 回覆:51 積分:13 註冊:2004-07-24 發送簡訊給我 |
hi 您好,我試用您的方法,可是有一問題,就是會有"重疊影像",
(因為我不知如何bmp transfert to gif or jpg,對不起,我沒上傳圖片o)
不知您有沒試過,我要不要把我code貼上來看看,還有,
我的code也無法清除縮小圖片下的的image2,
請教各位高手,小的不勝感激o 還有,非常不好意思,想請問,很感謝貴人回應,但我要如何評分,有無版規,
可relatedo 抱歉,我都用問的o Graphics::TBitmap *TheBitmap,*TempBitmap;
int Width,Height;
Byte *ptr1, *ptr2 ;
Byte *ptr3 ;
TempBitmap=new Graphics::TBitmap();
TheBitmap=Image1->Picture->Bitmap;
//TheBitmap->PixelFormap=pf8bit;
TempBitmap->Assign(TheBitmap);
Width=TheBitmap->Width;
Height=TheBitmap->Height; for( int j=0 ; j < Height/2 ; j++)
{
ptr1=(Byte*)TheBitmap->ScanLine[2*j];
ptr2=(Byte*)TheBitmap->ScanLine[2*j+1];
ptr3=(Byte*)TempBitmap->ScanLine[j]; for(int i=0 ; i < Width/2 ; i++ )
{
ptr3[i]=(BYTE)((ptr1[2*i]+ptr1[2*i+1]+ptr2[2*i]+ptr2[2*i+1])/4);
ptr1=ptr3;
}
}
/*
TempBitmap=Image2->Picture->Bitmap;
//TheBitmap=Image2->Picture->Bitmap;
TheBitmap->Assign(TempBitmap);
*/
Image2->Picture->Assign(TempBitmap);
delete TempBitmap;
//---------------------以上是我的code,請不吝惜指教o
|
brook
資深會員 發表:57 回覆:323 積分:371 註冊:2002-07-12 發送簡訊給我 |
|
TheMoon
中階會員 發表:17 回覆:95 積分:67 註冊:2002-06-05 發送簡訊給我 |
我之前提供的作法應該可以得到你要的結果,
只是Width和Height都假設成一定值,(Width=256,Height=256)
且假設影像為256色灰階影像,(PixelFormat=pf8bit)
因此要作256色灰階調色盤設定,(因為位元深度的關係)
請參考:http://delphi.ktop.com.tw/topic.php?topic_id=29259
所以條件被限制的比較多,須依你的需求去作修改。
結果如下:
我現在將你PO的程式整理如下:
Graphics::TBitmap *TheBitmap,*TempBitmap;
int Width,Height;
Byte *ptr1, *ptr2, *ptr3;
TempBitmap=new Graphics::TBitmap();
TheBitmap=Image1->Picture->Bitmap; //你將原圖 Assign 給 TheBitmap
TempBitmap->Assign(TheBitmap); //然後你又將 TheBitmap Assign 給 TempBitmap
//因此你原本要作縮圖的目的地 TempBitmap 便已經儲存了原圖影像
//而且 TempBitmap 的 property 也都和原圖一樣了
//包括Width、Height、PixelFormat
//所以下面迴圈裡的運算結果當然會出現疊圖效果囉
Width=TheBitmap->Width;
Height=TheBitmap->Height;
for( int j=0 ; j < Height/2 ; j++)
{
ptr1=(Byte*)TheBitmap->ScanLine[2*j];
ptr2=(Byte*)TheBitmap->ScanLine[2*j+1];
ptr3=(Byte*)TempBitmap->ScanLine[j]; for(int i=0 ; i < Width/2 ; i++ )
{
ptr3[i]=(BYTE)((ptr1[2*i]+ptr1[2*i+1]+ptr2[2*i]+ptr2[2*i+1])/4);
ptr1=ptr3;
}
}
Image2->Picture->Assign(TempBitmap);
delete TempBitmap; 結果如下:
|
TheMoon
中階會員 發表:17 回覆:95 積分:67 註冊:2002-06-05 發送簡訊給我 |
將你的程式修改一下,就沒疊圖問題了,
程式如下:
//Img1和Img2是TImage元件,且Img1已給定一張圖
//可能要注意一下Width和Height的奇數偶數問題,因為我沒作判斷
int Width,Height; Byte *ptr1, *ptr2, *ptr3; Width = Img1->Picture->Bitmap->Width; Height = Img1->Picture->Bitmap->Height; Graphics::TBitmap *TempBitmap = new Graphics::TBitmap(); TempBitmap->Width = (int)(Width/2); TempBitmap->Height = (int)(Height/2); TempBitmap->PixelFormat = pf24bit; //直接設成24bit的影像作處理,就不用作調色盤設定 for( int j=0 ; j < (int)(Height/2) ; j ) { ptr1=(Byte*)Img1->Picture->Bitmap->ScanLine[2*j]; ptr2=(Byte*)Img1->Picture->Bitmap->ScanLine[2*j 1]; ptr3=(Byte*)TempBitmap->ScanLine[j]; for(int i=0 ; i < (int)(Width/2) ; i ) { ptr3[i*3]=(BYTE)((ptr1[2*i] ptr1[2*i 1] ptr2[2*i] ptr2[2*i 1])/4); ptr3[i*3 1]=(BYTE)((ptr1[2*i] ptr1[2*i 1] ptr2[2*i] ptr2[2*i 1])/4); ptr3[i*3 2]=(BYTE)((ptr1[2*i] ptr1[2*i 1] ptr2[2*i] ptr2[2*i 1])/4); } } Img2->Picture->Assign(TempBitmap); delete TempBitmap;發表人 - taishyang 於 2004/07/29 19:46:55 |
kmp
一般會員 發表:17 回覆:51 積分:13 註冊:2004-07-24 發送簡訊給我 |
first, 非常謝謝以上兩位大人的幫忙o 我把我程式貼上,我覺這樣好像是對了,可是我的結果是長寬各半的空白圖o
//--------------------------------------------------------
//Graphics::TBitmap *TheBitmap,*TempBitmap; .....[1]
int Width,Height;
Byte *ptr1, *ptr2 ;
Byte *ptr3 ;
//TempBitmap=new Graphics::TBitmap();.........[2]
Graphics::TBitmap *TempBitmap = new Graphics::TBitmap(); //[1]+[2] //TheBitmap=Image1->Picture->Bitmap; //Assign original to TheBitmap <1>
//TempBitmap->Assign(TheBitmap); //Assign TheBitmap to TempBitmap <2>
//<1>,<2> 因此原本要縮圖的目的地 TempBitmap已儲存 TheBitmap,
// and the property of TempBitmap is the same TheBitmap.
//included Width, Height,PixelFormt
// so it would be overmap Width= Image1->Picture->Bitmap->Width ;//Width=TheBitmap->Width;
Height= Image1->Picture->Bitmap->Height ;//Height=TheBitmap->Height;
TempBitmap->Width = (int)(Width/2);
TempBitmap->Height = (int)(Height/2); for( int j=0 ; j < Height/2 ; j )
{
ptr1=(Byte*)Image1->Picture->Bitmap->ScanLine[2*j];
ptr2=(Byte*)Image1->Picture->Bitmap->ScanLine[2*j 1];
//ptr1=(Byte*)TheBitmap->ScanLine[2*j];
//ptr2=(Byte*)TheBitmap->ScanLine[2*j 1];
ptr3=(Byte*)TempBitmap->ScanLine[j]; for(int i=0 ; i < (int)(Width/2) ; i )
{
ptr3[i]=(BYTE)((ptr1[2*i] ptr1[2*i 1] ptr2[2*i] ptr2[2*i 1])/4);
//ptr1=ptr3;
}
}
/*
TempBitmap=Image2->Picture->Bitmap;
//TheBitmap=Image2->Picture->Bitmap;
TheBitmap->Assign(TempBitmap);
*/
// TempBitmap=Image2->Picture->Bitmap;
Image2->Picture->Assign(TempBitmap);
//TempBitmap=Image2->Picture->Bitmap;
delete TempBitmap;
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |