1. 創立一 BCB project。
2. 拉出三個Button(命名可自訂或參考以下範例),一個Memo用來輸出訊息,一個Image物件輸入圖片影像。
3. 於Image物件中的picture屬性指定一個影像來源(BMP / JPG),當然還有很多可以載入圖片的方法,如用OpenDialog或是直接在程式內設定檔案路徑等,不過並不是本文重點。
以下為程式碼:
//---------------------------------------------------------------------------
#include
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Image1->Height = Image1->Picture->Bitmap->Height;
Image1->Width = Image1->Picture->Bitmap->Width;
Memo1->ScrollBars = ssVertical;
Image1->Picture->Bitmap->PixelFormat = pf24bit;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button_scanlineClick(TObject *Sender)
{
int cur_time, r, g, b;
String str;
BYTE *ptr;
cur_time = GetTickCount();
for (int i = 0; i < Image1->Height; i++)
{
ptr = (Byte*)Image1->Picture->Bitmap->ScanLine[i];
for (int j = 0; j < Image1->Width; j++)
{
b = ptr[3*j];
g = ptr[3*j+1];
r = ptr[3*j+2];
}
}
str.sprintf("processing time : %0.3f",(float)(GetTickCount()-cur_time)/1000);
Memo1->Lines->Add(str);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button_PixelsClick(TObject *Sender)
{
int cur_time, r, g, b, color;
String str;
cur_time = GetTickCount();
for (int i = 0; i < Image1->Height; i++)
{
for (int j = 0; j < Image1->Width; j++)
{
color = Image1->Canvas->Pixels[j][i];
b = (color&0xFF0000) >> 16;
g = (color&0x00FF00) >> 8;
r = (color&0x0000FF);
}
}
str.sprintf("processing time : %0.3f",(float)(GetTickCount()-cur_time)/1000);
Memo1->Lines->Add(str);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button_GetRGBClick(TObject *Sender)
{
int cur_time, r, g, b;
String str;
cur_time = GetTickCount();
for (int i = 0; i < Image1->Height; i++)
{
for (int j = 0; j < Image1->Width; j++)
{
b = GetBValue(Image1->Canvas->Pixels[j][i]);
g = GetGValue(Image1->Canvas->Pixels[j][i]);
r = GetRValue(Image1->Canvas->Pixels[j][i]);
}
}
str.sprintf("processing time : %0.3f",(float)(GetTickCount()-cur_time)/1000);
Memo1->Lines->Add(str);
}
//---------------------------------------------------------------------------
可以看出第一種方是用ScanLine[i]抓取每列像素的方式速度最快,然後用內建的GetBValue等函是最慢,應該是被包裝太多層的原因,所以導致執行效率較差,取出的RGB值看是要用動態二維陣列,還是另行處理後寫檔就各自發揮。另外要注意的是由於只需要RGB的資料,所以可以指定 Image1->Picture->Bitmap->PixelFormat = pf24bit,若是指定為pf32bit,則ScanLine讀回來的每組資料會由4 Bytes組成。
沒有留言:
張貼留言