从BMP照片中提取内存初始化文件(MIF)

时间:2015-04-25 07:06:35

标签: java c intel-fpga quartus cyclone

我正在使用Quartus从Altera开发DE12-115微处理器。为了使用内置VGA连接在显示器上显示BMP图像,我必须首先将BMP图像转换为其MIF格式。 MIF格式只是一个查找表,它使用RGB颜色代码指定每个像素的地址和每种颜色的别名。样本MIF文件将具有以下形状

DEPTH = 32;                   -- The size of data in bits
WIDTH = 8;                    -- The size of memory in words
ADDRESS_RADIX = HEX;          -- The radix for address values
DATA_RADIX = BIN;             -- The radix for data values
CONTENT                       -- start of (address : data pairs)
BEGIN

00 : 00000000;                -- memory address : data
01 : 00000001;
02 : 00000010;
03 : 00000011;
04 : 00000100;
05 : 00000101;
06 : 00000110;
07 : 00000111;
08 : 00001000;
09 : 00001001;
0A : 00001010;
0B : 00001011;
0C : 00001100;

END;

我还没有找到任何可以让我将自己的图像转换为上述格式的软件。但是,我发现了一个C代码。由于我不熟悉C,我想知道是否有人可以帮助我理解代码,库导入等...以便我可以将其转换为JAVA。如果有人向我解释如何从照片中提取MIF格式并且我可以从头开始编写自己的代码,那也会很棒。 C代码如下。提前谢谢大家

// PicTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

//#ifndef LaserMaze_Bitmap_h
//#define LaserMaze_Bitmap_h


#pragma pack(2) // Add this

typedef struct
{
    unsigned short bfType;
    unsigned int   bfSize;
    unsigned short bfReserved1;
    unsigned short bfReserved2;
    unsigned int   bfOffBits;
} BITMAPFILEHEADER;

#pragma pack() // and this


#  define BF_TYPE 0x4D42             /* "MB" */

typedef struct                       /**** BMP file info structure ****/
{
    unsigned int   biSize;           /* Size of info header */
    int            biWidth;          /* Width of image */
    int            biHeight;         /* Height of image */
    unsigned short biPlanes;         /* Number of color planes */
    unsigned short biBitCount;       /* Number of bits per pixel */
    unsigned int   biCompression;    /* Type of compression to use */
    unsigned int   biSizeImage;      /* Size of image data */
    int            biXPelsPerMeter;  /* X pixels per meter */
    int            biYPelsPerMeter;  /* Y pixels per meter */
    unsigned int   biClrUsed;        /* Number of colors used */
    unsigned int   biClrImportant;   /* Number of important colors */

    unsigned int RedMask;       /* Mask identifying bits of red component */
    unsigned int GreenMask;     /* Mask identifying bits of green component */
    unsigned int BlueMask;      /* Mask identifying bits of blue component */
    unsigned int AlphaMask;     /* Mask identifying bits of alpha component */
    unsigned int CSType;        /* Color space type */
    long  RedX;          /* X coordinate of red endpoint */
    long  RedY;          /* Y coordinate of red endpoint */
    long  RedZ;          /* Z coordinate of red endpoint */
    long  GreenX;        /* X coordinate of green endpoint */
    long  GreenY;        /* Y coordinate of green endpoint */
    long  GreenZ;        /* Z coordinate of green endpoint */
    long  BlueX;         /* X coordinate of blue endpoint */
    long  BlueY;         /* Y coordinate of blue endpoint */
    long  BlueZ;         /* Z coordinate of blue endpoint */
    unsigned int GammaRed;      /* Gamma red coordinate scale value */
    unsigned int GammaGreen;    /* Gamma green coordinate scale value */
    unsigned int GammaBlue;     /* Gamma blue coordinate scale value */
} BITMAPINFOHEADER;

/*
 * Constants for the biCompression field...
 */

#  define BI_RGB       0             /* No compression - straight BGR data */
#  define BI_RLE8      1             /* 8-bit run-length compression */
#  define BI_RLE4      2             /* 4-bit run-length compression */
#  define BI_BITFIELDS 3             /* RGB bitmap with RGB masks */

typedef struct                       /**** Colormap entry structure ****/
{
    unsigned char  rgbBlue;          /* Blue value */
    unsigned char  rgbGreen;         /* Green value */
    unsigned char  rgbRed;           /* Red value */
    unsigned char  rgbReserved;      /* Reserved */
} RGBQUAD;


unsigned char *LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
    FILE *filePtr; //our file pointer
    BITMAPFILEHEADER bitmapFileHeader; //our bitmap file header
    unsigned char *bitmapImage;  //store image data int imageIdx=0;  //image index counter
    unsigned char tempRGB;  //our swap variable

    //open filename in read binary mode
    filePtr = fopen(filename,"rb");
    if (filePtr == NULL)
        return NULL;

    //read the bitmap file header
    fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER),1,filePtr);

    //verify that this is a bmp file by check bitmap id
    if (bitmapFileHeader.bfType !=0x4D42)
    {
        fclose(filePtr);
        return NULL;
    }

    //read the bitmap info header
    fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER),1,filePtr);

    //move file point to the begging of bitmap data
    fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);

    //allocate enough memory for the bitmap image data
    bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);

    //verify memory allocation
    if (!bitmapImage)
    {
        free(bitmapImage);
        fclose(filePtr);
        return NULL;
    }

    //read in the bitmap image data
    fread(bitmapImage,bitmapInfoHeader->biSizeImage,1,filePtr);

    //make sure bitmap image data was read
    if (bitmapImage == NULL)
    {
        fclose(filePtr);
        return NULL;
    }

    //swap the r and b values to get RGB (bitmap is BGR)
    /*for (imageIdx = 0,imageIdx < bitmapInfoHeader->biSizeImage;imageIdx+=3)
    {
        tempRGB = bitmapImage[imageIdx];
        bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
        bitmapImage[imageIdx + 2] = tempRGB;
    }*/
    //close file and return bitmap iamge data
    fclose(filePtr);
    return bitmapImage;
}
double round(double d)
{
  return floor(d + 0.5);
}


bool generateMIF(unsigned char *bitmapData, long tSize, char *file)
{
    FILE * pFile;
    pFile = fopen (file,"w");
    if (pFile==NULL)
    {
        printf("Unable to Open file to write \n");
        return 0;
    }
    char buff[40];
    sprintf(buff,"DEPTH = %d;\n",tSize/3);
    fputs("WIDTH = 8;\n",pFile);
    fputs(buff,pFile);
    fputs("ADDRESS_RADIX = HEX;\n",pFile);
    fputs("DATA_RADIX = HEX;\n",pFile);
    fputs("CONTENT BEGIN\n",pFile);
    long ind=0;
    long addr=0;
    for (ind=tSize-1;ind>=0; ind-=3)
    {

        unsigned char R=round(bitmapData[ind]/255.0*7.0);
        unsigned char G=round(bitmapData[ind-1]/255.0*7.0);
        unsigned char B=round(bitmapData[ind-2]/255.0*3.0);

        unsigned char Var = R *32 + G *4 + B;

        sprintf(buff,"%X : %X ;\n",addr,Var);
        fputs(buff,pFile);
        addr++;
    }
    fputs("END;\n",pFile);
    fclose (pFile);

}


bool generateLUTMIF(char *file)
{
    FILE * pFile;
    pFile = fopen (file,"w");
    if (pFile==NULL)
    {
        printf("Unable to Open file to write \n");
        return 0;
    }
    char buff[40];
    fputs("WIDTH = 24;\n",pFile);
    fputs("DEPTH = 256;\n",pFile);
    fputs("ADDRESS_RADIX = HEX;\n",pFile);
    fputs("DATA_RADIX = HEX;\n",pFile);
    fputs("CONTENT BEGIN\n",pFile);
    long ind=0;
    long addr=0;
    for (ind=0;ind<256; ind++)
    {
        unsigned char C=ind;
        unsigned char R=C >> 5;
        R = R* 255/7;
        unsigned char G= (C >> 2)&0x07;
        G= G* 255 / 7;

        unsigned char B=C & 0x3;
        B=B*255/3;


        sprintf(buff,"%X : %02X%02X%02X ;\n",ind,R,G,B);
        fputs(buff,pFile);
        addr++;
    }
    fputs("END;\n",pFile);
    fclose (pFile);

}



int _tmain(int argc, _TCHAR* argv[])
{
    printf("Reading Image... \n");
    BITMAPINFOHEADER bitmapInfoHeader;

    unsigned char *bitmapData;
    bitmapData = LoadBitmapFile("d:\\back_24.bmp",&bitmapInfoHeader);
    long tSize= bitmapInfoHeader.biHeight *bitmapInfoHeader.biWidth * 3 ;//24 bps 
    generateMIF(bitmapData,tSize,"D:\\backMIF.txt");
    generateLUTMIF("D:\\lutMIF.mif");
    printf("Done !");
    return 0;
}

2 个答案:

答案 0 :(得分:3)

尝试使用Matlab。它会变得如此简单。 如果你使用c,你应该定义一些结构,尝试跳转图片的标题。这毫无意义。但是如果你使用Matlab,你只需打开图片并获取数据! 这是我的Matlab代码,希望能帮到你:

  %mcode to create a mif file
    src = imread('lena.jpg');
    gray = rgb2gray(src);
    [m,n] = size( gray ); %size od your picture

    N = m*n; %your ram or rom depth。
    word_len = 8; 
    data = reshape(gray, 1, N);% reshape you picture's data

    fid=fopen('gray_image.mif', 'w'); % open mif file 
    fprintf(fid, 'DEPTH=%d;\n', N);
    fprintf(fid, 'WIDTH=%d;\n', word_len);

    fprintf(fid, 'ADDRESS_RADIX = UNS;\n'); 
    fprintf(fid, 'DATA_RADIX = HEX;\n'); 
    fprintf(fid, 'CONTENT\t');
    fprintf(fid, 'BEGIN\n');
    for i = 0 : N-1
    fprintf(fid, '\t%d\t:\t%x;\n',i, data(i+1));
    end
    fprintf(fid, 'END;\n'); % prinf the end
    fclose(fid); % close your file

答案 1 :(得分:1)

我正在开发一个关于将Altera FPGA配置为监视器的项目,因此我需要一个MIF文件生成器。我看到网上没有很多,有些甚至没有编译。

所以我决定在Java中编写自己的,它可以工作并处理几乎所有可能的错误。但是,该工具首先将图像转换为灰度,然后才会创建MIF文件。

您可以在GitHub上的我的页面上找到我的工具。