visited 13 states (5.77%)
Create your own visited map of The World or Triposo world travel guide for Android

2014-09-04

BCB應用於三種取出圖片像素之RGB值的方法與速度比較


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組成。

這些也是同標籤文章 :

沒有留言: