全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1596
推到 Plurk!
推到 Facebook!

如何用scanline存放改變後的二維陣列(我是新手)

尚未結案
kmp
一般會員


發表:17
回覆:51
積分:13
註冊:2004-07-24

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-07-27 15:27:59 IP:211.74.xxx.xxx 未訂閱
不好意思,我是新手,想請問如同前說過不是內插法和單純的縮小放大,利用 (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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-07-27 16:30:26 IP:202.39.xxx.xxx 未訂閱
程式中用到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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-07-27 17:09:33 IP:211.74.xxx.xxx 未訂閱
我不太有寫程式經驗,想問一個可能很簡單基本的問題,如下在//中:    
引言: 程式中用到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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-07-27 17:54:33 IP:202.39.xxx.xxx 未訂閱
抱歉,之前沒看清楚問題。< > 補充了一個建議作法如前, 試試看囉。< >
brook
資深會員


發表:57
回覆:323
積分:371
註冊:2002-07-12

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-07-27 18:59:35 IP:218.160.xxx.xxx 未訂閱
 
  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;jHeight/2;j  )
  {
    ptr1=(Byte*)A->ScanLine[2*j];
    ptr2=(Byte *)A->ScanLine[2*j 1]; //A圖需2個指標
    ptr3=(Byte *)B->ScanLine[j];     //B圖        for(i=0;iWidth/2;i  )
    {
      ptr3[i]=(BYTE)((ptr1[2*i] ptr1[2*i 1] ptr2[2*i] ptr2[2*i 1])/4);
    }
  }
kmp
一般會員


發表:17
回覆:51
積分:13
註冊:2004-07-24

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-07-28 22:38:15 IP:211.74.xxx.xxx 未訂閱
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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-07-29 13:13:28 IP:218.160.xxx.xxx 未訂閱
會有"重疊影像"? 我覺得會有影像失真吧?,因為用你的縮圖公式,倒不如直接用CopyRect,失真程度反而小一點,而且bcb有現成的列子,放大縮小幾倍都沒問題,參考看看!
TheMoon
中階會員


發表:17
回覆:95
積分:67
註冊:2002-06-05

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-07-29 16:40:54 IP:202.39.xxx.xxx 未訂閱
我之前提供的作法應該可以得到你要的結果, 只是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

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-07-29 16:52:35 IP:202.39.xxx.xxx 未訂閱
將你的程式修改一下,就沒疊圖問題了, 程式如下: //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

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-08-04 09:52:29 IP:211.74.xxx.xxx 未訂閱
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;
系統時間:2024-05-10 5:30:08
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!