如何将每个字节代表4个像素(每个像素2位)的字节阵列转换为19200字节的大小,以排列为320x240字符的位图

StackOverflow https://stackoverflow.com/questions/2969208

  •  24-10-2019
  •  | 
  •  

我正在与仪器(控制它的遥控器)进行交流,然后
我需要做的一件事是绘制仪器屏幕。

为了获得屏幕,我发出命令和仪器
用代表屏幕的字节数组回复。

以下是仪器手册在将响应转换为实际屏幕的说法:

该命令检索显示显示的帧缓冲数据。
它的大小为19200字节,每个像素2位,每个字节排列为4像素
320x240特征。
数据以RLE编码形式发送。
要将这些数据转换为用于Windows中的BMP,它必须为
变成4BPP。另请注意,BMP文件相对颠倒
对于此数据,即顶级显示行是BMP中的最后一行。

我设法解开了数据,但是现在我一直坚持如何实际
从未包装的字节阵列转到位图。

我的背景非常接近零,我的搜索
也没有透露太多。

我正在寻找可以用来帮助我的说明和/或文章
解开如何完成此操作。

任何代码甚至伪代码也将有所帮助。 :-)

因此,仅总结这一切:

如何将19200字节的字节阵列大小转换
每个字节代表4个像素(每个像素2位),
以320x240个字符排列的位图。

提前致谢。

有帮助吗?

解决方案

要做类似的事情,您将需要这样的例程:

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];
}

其他提示

如果您每个像素有两个位,则对于每个像素,您都有4种不同的颜色。颜色可能是索引或只是硬编码(即0表示黑色,1个白色等)。

不知道这是否有太大帮助(我不知道您使用的是什么位图对象,但也许它具有常规的RGB或ARGB方案,每个频道1个字节),但是在伪actionscript中,我认为您应该做这样的事情。

//  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
    }
}

可以说,以上代码只是为了给您一个想法(希望!),并且基于一些假设,例如如何将这四个像素存储在字节中。

希望这是有道理的。

我不知道这是否有帮助,我将其用于从稀有旧硬件中获得的数据:

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

        }
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top