解压特殊的rle - imageproc

时间:2016-05-16 08:11:47

标签: c++ image-processing

我正在尝试解压缩以特殊方式压缩的rle文件。 我正在回到一个与原始图像不同的图像,我无法理解为什么。 第一个Ill解释它被压缩的方式: 原始图像是灰色图像,其中只有2种像素:白色或黑色。 在压缩中,他们使用一个字节来表示每个像素序列。 每个字节中的MSB位表示白色(= 1)或黑色(= 0)。另外7位表示序列,因此最大值可以为127。 例如,127个像素的白色将是:11111111B => 255 DEC。
127DEC也代表127个黑色像素(MSB为0)。 原始图像是120x240 BMP,我使用一个已知的功能(它给我)来保存BMP文件,因此如果遵循所有规则,将数组保存到bmp文件没有问题。 同样在压缩文件中,前2个BYTE将表示数组大小。 arraysize = rle [0] * 256 + rle [1]。

我只在这里放置解压缩和压缩的部分(我建两个)

void RleDeCompress(unsigned char rleimage[2 + 240 * 120], unsigned char decompressedimage[][NUMBER_OF_COLUMNS])
{
// 1st MSB bit from the 8 bit of each cell in the array represent color - Black or White
//2nd~7th BIT represent the number of times the color repeats itself
// first 2 cells in the array are represent the size of the array



int arraysize = rleimage[0] * 256 + rleimage[1];
int row = 0;
int col = 0;
unsigned char colormask = 128; //binary 10000000=128dec
unsigned char multiplymask = 127; // binary 01111111 = 127dec

unsigned int total = 0;
for (int i = 2; i < arraysize+2; i++)
{
    unsigned char blackorwhitebinary = (rleimage[i] & colormask) >> 7 ; // mask only the msb and then shift it to be the lsb
    unsigned char color = 255 * blackorwhitebinary; // decide if this is black or white 
    unsigned char multiply = rleimage[i] & multiplymask; // number of times the color repeats itself



    for (int j = 0; j < multiply; j++)
    {
        decompressedimage[row][col] = color;
        col++;
        if (col == NUMBER_OF_COLUMNS)
        {
            row++;
            col = 0;
        }

        if (row > NUMBER_OF_ROWS) cout << "error too many rows " << endl;

    }


    total += multiply;
    // check total of cells real in the binary file



}

cout << "total is:" << total << endl;



}








void RleCompress(unsigned char image[][NUMBER_OF_COLUMNS], unsigned char RleImage[2 + 240 * 120])
{
    unsigned char n = 0;
unsigned int N = 2;
unsigned int arrsize=0;
unsigned char temparray[ 240 * 120];
for (int row = 0; row < NUMBER_OF_ROWS; row++)
{
    for (int column = 0; column < NUMBER_OF_COLUMNS; column++)
    {
        temparray[arrsize] = image[row][column] / 255;
        arrsize++;
    }
}
for (int i = 0; i < arrsize; i++)
{
    n++;
    if (n == 127)
    {
        RleImage[N+2] = temparray[i] * 128 + n;
        n = 0;
        N++;
    }
    else
    {
        if (i == arrsize)
        {
            RleImage[N + 2] = temparray[i] * 128 + n;
        }
        else
        {
            if (temparray[i] != temparray[i + 1])
            {
                RleImage[N + 2] = temparray[i] * 128 + n;
                n = 0;
                N++;
            }
        }
    }
}
RleImage[0] = N / 256;
RleImage[1] = N % 256;
}




void SaveRleFile(unsigned char RleImage[2 + 240 * 120])
{
ofstream myfile;
myfile.open("P01C.bin", ios::out | ios::binary);

if (myfile.is_open())
{
    int index = 0;
    while (index < 2 + 120 * 240)
    {
        myfile << RleImage[index];
        index++;
    }
    cout << "index is :" << index << endl;
}

myfile.close();

}






void LoadRleBinFile(char binfilename[], unsigned char * image)
{
//for (int j = 0; j < 2 + 120 * 240; j++) image[j] = 255; //clears the array from garbage and sets all of it to white.

ifstream myfile;
char c;
int i = 0;
myfile.open(binfilename, ios::in | ios::binary); // open file in binary mode input only
if (myfile.is_open())
{
    while (!myfile.eof())
    {
        myfile.get(c);
        image[i] = (unsigned char) c;
        i++;


    }
}
else
    cout << "error while opening file " << endl;


myfile.close();
}

void main()
{

unsigned char GrayImage[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];
unsigned char Rlearray[2 + 240 * 120]; //rlearray size is unknown  when first initialzing . worst case is 2 + 240*120
 LoadGrayImageFromTrueColorBmpFile(GrayImage, "P01A.bmp");
 StoreGrayImageAsGrayBmpFile(GrayImage, "P01B.bmp");
//--------------------------------------------------------------------------------------------------------------------------
 ConvertGrayImageToBlackWhite(GrayImage);
 StoreGrayImageAsGrayBmpFile(GrayImage, "P01B2.bmp");

 RleCompress(GrayImage, Rlearray);
 SaveRleFile(Rlearray);
LoadRleBinFile("P01C.rle", Rlearray);
RleDeCompress(Rlearray, GrayImage);
StoreGrayImageAsGrayBmpFile(GrayImage, "P01C.BMP");

//WaitForUserPressKey();
}

我找到了一种检查问题的方法,它在代码中。 图片中的像素数量(120 * 240 = 28800)应该是,或者至少对我而言似乎是最合乎逻辑的,等于所有序列的总和,因为如果没有,那么我们没有压缩整个图像。 在我的代码中,所有序列的总和约为17000。 != 28800。 我不明白,如果我没有正确压缩或没有解压缩,但从查看二进制文件(使用二进制查看器程序),似乎二进制文件是正常的。

0 个答案:

没有答案