在MATLAB中将图像编码为base64字符串

时间:2018-04-11 20:33:12

标签: html image matlab base64

目前,我在MATLAB中将图像存储为MxNx3 uint8数组。但是,我需要将其嵌入到HTML文档中,并且我不能单独包含该图像。

相反,我决定尝试将图像编码为base64字符串。但是,我似乎找不到一种方法来将图像编码为字符串,而不必首先将图像保存到磁盘。我试着调查writebmp之类的东西,但我似乎无法让它发挥作用。

我真的不想图像写入文件,只是使用fread将其读回来。我正在使用的计算机具有非常低的磁盘I / O,因此方式的时间太短。

任何帮助将不胜感激!

编辑:

我看了here,但由于“找不到方法”,R2018b中的错误。当我线性化图像时,返回的字符串不正确

1 个答案:

答案 0 :(得分:1)

从图像矩阵到HTML

1将图像转换为BMP的字节

function [header] = writeBMP(IM)
header = uint8([66;77;118;5;0;0;0;0;0;0;54;0;0;0;40;0;0;0;21;0;0;0;21;0;0;0;1;0;24;0;0;0;0;0;64;5;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0]);
IMr = IM(:,:,1);
IMg = IM(:,:,2);
IMb = IM(:,:,3);clear IM;
IM(:,:,1)=IMb';
IM(:,:,2)=IMg';
IM(:,:,3)=IMr';
IM(:,:,:)=IM(:,end:-1:1,:);
[i,j,~]=size(IM);
header(19:22) = typecast(int32(i),'uint8'); %width
header(23:26) = typecast(int32(j),'uint8'); %height
IM = permute(IM,[3,1,2]);
IM = reshape(IM,[i*3,j]);
W = double(i)*3;
W = ceil(W/4)*4;
IM(3*i+1:W,:)=0; %padd zeros
IM = IM(:); %linear
header(35:38) = typecast(uint32(length(IM)),'uint8'); %datasize
header = [header;IM];
header(3:6) = typecast(uint32(length(header)),'uint8'); %filesize
end

您还可以查看...\toolbox\matlab\imagesci\private\writebmp.m以获取更详细的示例。

2将字节编码为base64字符

最好在mex文件中完成。 将此代码保存为encodeB64.c并运行mex encodeB64.c

/*==========================================================
 * encodeB64.c - converts a byte vector to base64
 *
 * The calling syntax is:
 *
 *      [B] = encodeB64(B)
 *
 *      input:   - B     : vector of uint8
 *
 *      output:  - B     : vector of base64 char
 *
 * This is a MEX-file for MATLAB.
 *
 *========================================================*/

#include "mex.h" 

/* The computational routine */
void Convert(unsigned char *in, unsigned char *out,unsigned long Nin, unsigned long Nout)
{
    int temp; 
    static unsigned char alphabet[64] = {65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,48,49,50,51,52,53,54,55,56,57,43,47};
    for (int i=0;i<(Nin-2);i+=3){
        temp = in[i+2] | (int)in[i+1]<<8 | (int)in[i]<<16;
        for (int j=0;j<4;j++){
            out[3+(i/3)*4-j] = alphabet[(temp >> (j*6)) & 0x3f];
        }
    }
    if (Nin%3==1){
        temp = (int)in[Nin-1]<<16;
        out[Nout-1] = 61;
        out[Nout-2] = 61;
        out[Nout-3] = alphabet[(temp >> 12) & 0x3f];
        out[Nout-4] = alphabet[(temp >> 18) & 0x3f];
    }
    if (Nin%3==2){
        temp = in[Nin-1]<<8 | (int)in[Nin-2]<<16;
        out[Nout-1] = 61;
        out[Nout-2] = alphabet[(temp >> 6) & 0x3f];
        out[Nout-3] = alphabet[(temp >> 12) & 0x3f];
        out[Nout-4] = alphabet[(temp >> 18) & 0x3f];
    }
}

/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
    unsigned char *InputV;           /* input vector 1*/
    unsigned char *OutputV;          /* output vector 1*/
    unsigned long Nin;
    unsigned long Nout;

    /* check for proper number of arguments */
    if(nrhs!=1) {
        mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs","One inputs required.");
    }
    if(nlhs!=1) {
        mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs","One output required.");
    }
     /* make sure the first input argument is scalar integer*/
    if( !mxIsClass(prhs[0],"uint8") || mxGetNumberOfElements(prhs[0]) == 1 || mxGetN(prhs[0]) != 1)  {
        mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notRowInteger","Input one must be uint8 column vector.");
    }

    /* get the value of the scalar input  */
    InputV = mxGetPr(prhs[0]);
    Nin = mxGetM(prhs[0]); /*number of input bytes */
    Nout = 4*((Nin+2)/3);

    /* create the output matrix */
    plhs[0] = mxCreateNumericMatrix((mwSize)Nout,1,mxUINT8_CLASS,mxREAL);

    /* get a pointer to the real data in the output matrix */
    OutputV = (unsigned char *) mxGetData(plhs[0]);

    /* call the computational routine */
    Convert(InputV,OutputV,Nin,Nout);
}

要测试它,你可以运行

T = randi(255,[2^28,1],'uint8'); %250MB random data
tic;Res=encodeB64(T);t=toc       %convert
(length(T)/2^20) / t             %read in MB/s
(length(Res)/2^20) / t           %write in MB/s

我的结果:

  

读:467 MB / s写:623 MB / s

3将它们放在一起并测试

file = 'test.html';
fid = fopen(file,'wt');
fwrite(fid,sprintf('<html>\n<header> </header>\n<body>\n'));
fwrite(fid,sprintf('<p>%s</p>\n','Show the Matlab demo image street1.jpg'));
IM = imread('street1.jpg');figure(1);clf;image(IM);
B = writeBMP(IM);
str = encodeB64(B);
fwrite(fid,sprintf('<img src="data:image/bmp;base64,%s"/>\n',str));
fwrite(fid,sprintf('</body>\n</html>'));
fclose(fid);
  

这应生成一个带有图像编码的1,229,008字节HTML文件。