从BMP图片中提取存储器初始化文件(MIF)

从BMP图片中提取存储器初始化文件(MIF)

问题描述:

我正在使用Quartus从Altera获得DE12-115微处理器。为了使用内置的VGA连接将BMP图像显示到监视器上,我必须首先将BMP图像转换为MIF格式。 MIF格式不过是一个查找表,它使用RGB颜色代码指定每个像素的地址和每种颜色的别名。 A样品MIF文件将具有以下形状从BMP图片中提取存储器初始化文件(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; 
} 

尝试使用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 
+0

非常感谢!但是,我对matlab不熟悉,请介绍一下如何编译代码并添加图片?感谢一群朋友! – dou2abou

+0

@ dou2abou如果你使用Matlab,你不需要编译代码。只需在matlab中打开代码,然后将您的图片放入代码所在的路径中。并点击“运行”按钮。当然你会改变文件名。 –

我在有关配置Altera FPGA中的监视项目的工作,所以我需要一个MIF文件生成器。我看到网上没有很多,有些甚至没有编译。

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

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