2010-06-03 96 views
1

我正在與儀器進行通信(遠程控制它)和
其中之一我需要做的事情是繪製儀器屏幕。如何將每個字節代表4像素(每像素2位)的19200字節大小的字節數組轉換爲320x240字符的位圖

爲了獲得屏幕,我發出一個命令,儀器
以表示屏幕的字節數組答覆。

下面是什麼儀器手冊必須說關於該響應轉換爲實際屏幕:

該命令將檢索用於顯示的幀緩衝器數據。
它的大小爲19200字節,每像素2位,每字節4個像素排列爲
320x240字符。
數據以RLE編碼形式發送。
要將此數據轉換爲用於Windows的BMP,需要將其轉換爲4BPP,即
。還要注意的是,相對於該數據,BMP文件相對於
是顛倒的,即頂部顯示行是BMP中的最後一行。

我設法解開數據,但現在我停留在如何實際
從解壓縮字節數組位圖去。

我的背景是非常接近於零,我的搜索
還沒有透露很多。

我正在尋找指導和/或我可以用來幫助我的文章
undestand如何完成這項工作。

任何代碼或甚至僞代碼也將有所幫助。 :-)

所以,僅僅總結這一切:

如何轉換的19200個字節的大小,其中
每個字節表示4個像素(每像素2個比特),
一個字節數組將其排列爲320x240個字符的位圖。

在此先感謝。

回答

2

要做到這樣的事情,你會想這樣的一個程序:

Bitmap ConvertToBitmap(byte[] data, int width, int height) 
{ 
    Bitmap bm = new Bitmap(width, height, PixelFormat.Format24bppRgb); 
    for (int y=0; y < height; y++) { 
     for (int x=0; x < width; x++) { 
      int value = ReadPixelValue(data, x, y, width); 
      Color c = ConvertValToColor(value); 
      bm.SetPixel(x, y, c); 
     } 
    } 
    return bm; 
} 
從這裏

,你需要ReadPixelValue和ConvertValToColor。

static int ReadPixelValue(byte[] data, int x, int y, width) 
{ 
    int pixelsPerByte = 4; 
    // added the % pixelsPerByte to deal with width not being a multiple of pixelsPerByte, 
    // which won't happen in your case, but will in the general case 
    int bytesPerLine = width/pixelsPerByte + (width % pixelsPerByte != 0 ? 1 : 0); 
    int index = y * bytesPerLine + (x/pixelsPerByte); 
    byte b = data[index]; 

    int pixelIndex = (x % pixelsPerByte) * 2; 
    // if every 4 pixels are reversed, try this: 
    // int pixelIndex = 8 - (x % pixelsPerByte) * 2; 
    return ((int b) >> pixelIndex) & 0x3;   
} 

基本上,我從每個字節中取出每組兩位,並將其作爲int返回。

至於轉換爲顏色由您決定如何使4個值的頭部或尾部回來。 最有可能的,你可以做這樣的事情:

static Color[] _colors = new Color[] { Color.Black, Color.Red, Color.Blue, Color.White }; 
static Color ConvertValToColor(int val) 
{ 
    if (val < 0 || val > _colors.Length) 
     throw new ArgumentOutOfRangeException("val"); 
    return _colors[val]; 
} 
+0

感謝一堆基座。有效。 我確實必須使用「反向」代碼。 這對我來說都是黑魔法,所以我有一些學習要做。 :-) 但是,它的工作原理,這太棒了。 – Klinger 2010-06-04 04:31:08

1

如果每個像素有兩個比特,那麼每個像素都有4種不同的可能顏色。顏色索引或硬編碼(即0代表黑色,1白色等)。我不知道這是否有很大的幫助(我不知道你使用的是什麼位圖對象,但是它可能有一個正常的RGB或ARGB方案,每個通道只有一個字節),但是在僞動作腳本中,我認爲你應該這樣做。

// 80 -> 320/4 
for(var x:int = 0; x < 80; x++) { 
    for(var y:int = 0; y < 240; y++) { 
     var byteVal:int = readByte(); 

     var px_1:int = (byteVal >> 6) & 0x03; 
     var px_2:int = (byteVal >> 4) & 0x03; 
     var px_3:int = (byteVal >> 2) & 0x03; 
     var px_4:int = (byteVal) & 0x03; 

     // map your pixel value to ARGB 
     px_1 = getPixelValue(px_1); 
     px_2 = getPixelValue(px_2); 
     px_3 = getPixelValue(px_3); 
     px_4 = getPixelValue(px_4);  
     // assuming setPixel(x,y,pixelValue) 
     setPixel((x * 4), y, px_1); 
     setPixel((x * 4) + 1, y, px_2); 
     setPixel((x * 4) + 2, y, px_3); 
     setPixel((x * 4) + 3, y, px_4); 


    } 
} 

function getPixelValue(idx:int):uint { 
    // just an example... 
    switch(idx) { 
     case 0:  return 0xff000000; // black 
     case 1:  return 0xffffffff; // white 
     case 2:  return 0xffff0000; // red 
     case 3:  return 0xff0000ff; // blue 
    } 
} 

上面的代碼,我只想說,只是給你一個想法(希望!),並基於這樣的四個像素是如何存儲在一個字節的一些假設。

希望它是有道理的。

+0

您的代碼有很大的意義。 – Klinger 2010-06-18 06:15:13

0

我不知道這是否會有所幫助,我用這個數據我患有一種罕見的老硬件有:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Drawing; 
using System.IO; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      byte[] imageBytes = new byte[19201]; 
      //(Fill it with the data from the unit before doing the rest). 
      Bitmap bmp_workarea = new Bitmap(320, 240, System.Drawing.Imaging.PixelFormat.Format4bppIndexed); 
      Image newImage = Image.FromStream(new MemoryStream(imageBytes)); 
      using (Graphics gr = Graphics.FromImage(bmp_workarea)) 
      { 
       gr.DrawImage(newImage, new Rectangle(0, 0, bmp_workarea.Width, bmp_workarea.Height)); 
      } 
      //now you can use newImage, for example picturebox1.image=newimage 

     } 
    } 
} 
+0

當我看到其他答案時,也許我誤解了這個問題...... – Stefan 2010-06-03 20:12:10

+0

他的數據是每像素2位,而不是每像素4位,所以這會失敗。 – plinth 2010-06-03 20:12:48