Get Pixel from BitmapSource

Pada .NET 2.0 data bitmap dapat diakses melalui kelas System.Drawing.Bitmap, dan syntaxnya lumayan sederhana dan mudah, hanya dengan :

System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(“Namafile.bmp”);

Kita sudah dapat membuka file bitmap untuk dimodifikasi, namun kelemahan dari kelas ini adalah tidak support untuk data yang besar, atau memiliki format khusus ( dalam hal ini pengalaman saya adalah file TIFF 16-bit dengan besar 6000 x 6000 pixel, yaitu file USGS untuk data SRTM ), saya mengalami beberapa kali segmentation fault saat menggunakan class ini.

Pada .NET 3.0, tepatnya pada Windows Presentation Foundation (WPF) terdapat kelas bitmap lain yaitu System.Windows.Media.Imaging.BitmapSource yang merupakan file bitmap standard yang dapat digunakan untuk menyimpan data image untuk di manipulasi, class ini agak sedikit repot untuk digunakan, namun terbukti handal untuk membuka file berukuran besar dengan format khusus, berikut adalah contoh cara untuk membuka file image dengan menggunakan class BitmapSource.

/// Membuat stream source sebagai sumber data untuk membuka file image           

System.IO.Stream StreamSource = new FileStream (“namafile.tiff”, FileMode.Open, FileAccess.Read, FileShare.Read); 

///Membuat decoder sesuai dengan file yang ingin dibuka

///Selain TiffBitmapDecoder ada juga PNGBitmapDecoder, JPEGBitmapDecoder dan lain2

System.Windows.Media.Imaging.TiffBitmapDecoder decoder = new TiffBitmapDecoder(StreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);

/// Membuat sebuah bitmapSource dan menggassign frame pertama yang didapat oleh decoder ke bitmap source tersebut

/// Untuk beberapa jenis image seperti GIF & TIFF, sebuah file bisa terdiri dari beberapa frame

BitmapSource bitmapSource = decoder.Frames[0];

BitmapSource teleh selesai diambil dan siap untuk digunakan, namun, bagaimana caranya untuk mengambil informasi pixel dari sebuah bitmapsource ? karena pada bitmapsource tidak disediakan method GetPixel atau SetPixel seperti pada kelas Bitmap pada .NET 2.0

Untuk mendapatkan keterangan pixel pada posisi (x,y) kita perlu sedikit melakukan workaround dengan step sebagai berikut : 1. Mengambil data array of byte dari bitmapsource: 2. menentukan posisi pixel yang diinginkan dan mengkonversi posisi pixel ke posisi byte pada bitmapsource: 3. Mengkonversi byte menjadi nilai warna yang dimaksud

Berikut adalah class untuk mengcopy array of byte dari bitmap source ke byte[]

private byte[] GetArrayOfPixels(BitmapSource bitmapsource)

{

    Int32 stride = bitmapsource.PixelWidth * bitmapsource.Format.BitsPerPixel / 8;

    Int32 ByteSize = stride * bitmapsource.PixelHeight * bitmapsource.Format.BitsPerPixel/8;

    byte[] arrayofpixel = new byte[ByteSize];

    bitmapsource.CopyPixels(arrayofpixel, stride, 0);

    return arrayofpixel;

}

Dan ini adalah class untuk mengambil data color tertentu dari posisi pixel (x,y), class ini bertujuan untuk mengambil data warna dari sebuah image tiff 8bit grayscale ( hanya ada 256 warna saja )

private Color ConvertPixelValue(byte[] pixelsvalue, int x, int y)

{

    int NumOfBytes = format.BitsPerPixel / 8;

    int StartPosition = (y * ImageWidth * (format.BitsPerPixel / 8)) + ( x * (format.BitsPerPixel / 8) );

   

    // untuk mengembalikan dalam bentuk System.Windows.Media.Color

    byte colorvalue = pixelsvalue[StartPosition];

    return System.Windows.Media.Color.FromRgb(colorvalue, colorvalue, colorvalue);

    // Untuk mengembalikan dalam bentuk System.Drawing.Color

    int colorvalue = Convert.ToInt32(pixelsvalue[StartPosition]);

    return System.Drawing.Color.FromArgb(colorvalue,colorvalue,colorvalue);

}

Sehingga Line Of Code akan menjadi seperti ini :

/// Membuat stream source sebagai sumber data untuk membuka file image           

System.IO.Stream StreamSource = new FileStream (“namafile.tiff”, FileMode.Open, FileAccess.Read, FileShare.Read); 

///Membuat decoder sesuai dengan file yang ingin dibuka

///Selain TiffBitmapDecoder ada juga PNGBitmapDecoder, JPEGBitmapDecoder dan lain2

System.Windows.Media.Imaging.TiffBitmapDecoder decoder = new TiffBitmapDecoder (StreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);

/// Membuat sebuah bitmapSource dan menggassign frame pertama yang didapat oleh decoder ke bitmap source tersebut

/// Untuk beberapa jenis image seperti GIF & TIFF, sebuah file bisa terdiri dari beberapa frame

BitmapSource bitmapSource = decoder.Frames[0];

/// Mengcopy data bitmapsource ke dalam array of byte

byte[] arrayofpixels = GetArrayOfPixels(bitmapSource);

/// Mengambil data Color tertentu untuk pixel pada posisi ( 0, 1 )

Color c = ConvertPixelValue ( arrayofpixels, 0, 1 );

Conclusion

Class BitmapSource memang memerlukan cukup banyak workaround hanya untuk mengambil data 1 buah pixel saja, namun disisi lain, dengan tipe data seperti itu bitmapsource akan sangat mudah dan cepat digunakan untuk melakukan image processing, mungkin pada bagian selanjutnya saya akan mencoba menerangkan image processing dengan menggunakan WPF

By Andri Mirandi

_______________________________________________________________________________________

Junior Programmer at PT CITA Inovasi Rekaprima

andri@cinovasi.com / andri_mirandi@yahoo.com

Share this post: | | | |
Published Tuesday, August 28, 2007 8:28 AM by De_Joker

Comments

# re: Get Pixel from BitmapSource

Monday, March 24, 2008 11:29 AM by dewa

bagaimana mengonversi image ukuran 64x64 menjadi deretan pixel2? menggunakan VB6... mohon dibantu...saya sedang tertarik dengan VB tapi bingung pake VB6 untuk tujuan di atas...makasih mas....

Powered by Community Server (Commercial Edition), by Telligent Systems