Search code examples
matlabencodingutf-8windows-1252

MatLab: Open JPEG binary data as Image


I'm running into problems trying to open the binary data I've read into MatLab using fread(). My first approach was saving the image using fwrite(), but MatLab seems to always be defaulting to Windows-1252 encoding, which looses some of the data when writing. (If I open the original input and the output, the content is identical, except for the output missing characters like "ÿØÿà", which obviously means the image is getting corrupted.

I did not find a way to work around this encoding problem.

While I do think this apporach should be working, I also don't really want to write the data to a file before opening it. Just immediately creating an image variable would be preferable. I did not find a solution for doing it this way, though.

My current code:

Reading the image data

fid = fopen("ente2.jpg",'rb');
bytes = fread(fid);
fclose(fid);

Saving the image

outfile = 'out.jpg';
[fid, msg] = fopen(outfile, 'w', "n","UTF-8");
if fid < 0
  error('Failed to create file "%s" because "%s"', outfile, msg);
end
fwrite(fid, bytes, 'uint32');
fclose(fid);

Opening the image

p = imread(outfile);
figure();
imshow(outfile);

Solution

  • The approach is correct but your implementation has few issues:

    • bytes = fread(fid); Reads the data as uint8 elements, but convert the data to class double.
      For avoiding the automatic conversion use: bytes = fread(fid, '*uint8');.
      Code sample that shows that class is double:

       fid = fopen('football.jpg', 'rb');
       bytes = fread(fid); % The MATLAB default is converting data to class double
       display(class(bytes)) % double
       fclose(fid);
      
    • When saving the data to file, you should not set the encoding.
      Only text files uses encoding.
      You are writing the data into binary file, and binary files are just sequence of bytes (there is no encoding).
      Open a binary file for writing:

       [fid, msg] = fopen(outfile, 'wb');
      
    • fwrite(fid, bytes, 'uint32'); saves bytes as type 'uint32'.
      You need to save bytes as uint8:

       fwrite(fid, bytes, 'uint8');
      

    Complete code sample:

    % Reading the image data
    fid = fopen('football.jpg', 'rb');
    bytes = fread(fid, '*uint8'); % Use '*uint8' to keep data in uint8 class
    display(class(bytes)) % displays uint8
    fclose(fid);
    
    % Saving the image
    outfile = 'out.jpg';
    [fid, msg] = fopen(outfile, 'wb');
    if fid < 0
        error('Failed to create file "%s" because "%s"', outfile, msg);
    end
    %fwrite(fid, bytes, 'uint32'); % Why saving as uint32?
    fwrite(fid, bytes, 'uint8');
    fclose(fid);
    
    % Opening the image
    p = imread(outfile);
    figure();
    imshow(outfile);
    

    Result:
    enter image description here