【问题标题】:MatLab: Open JPEG binary data as ImageMatLab:将 JPEG 二进制数据作为图像打开
【发布时间】:2021-08-19 12:02:13
【问题描述】:

我在尝试使用 fread() 打开已读入 MatLab 的二进制数据时遇到问题。 我的第一种方法是使用 fwrite() 保存图像,但 MatLab 似乎总是默认为 Windows-1252 编码,这会在写入时丢失一些数据。 (如果我打开原始输入和输出,内容是相同的,除了输出缺少“ÿØÿà”之类的字符,这显然意味着图像已损坏。

我没有找到解决此编码问题的方法。

虽然我确实认为这个方法应该可以工作,但我也不想在打开文件之前将数据写入文件。最好立即创建一个图像变量。不过,我没有找到解决方案。

我当前的代码:

读取图像数据

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

保存图片

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);

打开图片

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

【问题讨论】:

  • 所以你有一个文件ente2.jpg,你读入它的所有字节,把它们写到一个新文件中,本质上是创建一个文件的副本,然后使用imread读入那个副本。为什么不直接用imread读入原文件呢?我不明白你想在这里完成什么。
  • 如果JPEG文件的二进制数据来自其他地方,您可以使用函数such as this one对其进行解码并生成原始像素数据。

标签: matlab encoding utf-8 windows-1252


【解决方案1】:

该方法是正确的,但您的实现几乎没有问题:

  • bytes = fread(fid); 将数据读取为uint8 元素,但将数据转换为double 类。
    为了避免自动转换使用:bytes = fread(fid, '*uint8');.
    显示该类为 double 的代码示例:

     fid = fopen('football.jpg', 'rb');
     bytes = fread(fid); % The MATLAB default is converting data to class double
     display(class(bytes)) % double
     fclose(fid);
    
  • 将数据保存到文件时,您应该设置编码。
    只有文本文件使用编码。
    您正在将数据写入二进制文件,而二进制文件只是字节序列(没有编码)。
    打开二进制文件进行写入:

     [fid, msg] = fopen(outfile, 'wb');
    
  • fwrite(fid, bytes, 'uint32');bytes 保存为'uint32' 类型。
    您需要将bytes另存为uint8

     fwrite(fid, bytes, 'uint8');
    

完整的代码示例:

% 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);

结果:

【讨论】:

  • 在 Windows 上,最好明确指定要编写二进制文件:fopen(outfile, 'wb')。我不确定默认值是什么,但这是一个非常重要的区别,最好明确说明它。在 POSIX 系统上,文本模式和二进制模式没有区别,因此标志在那里无关紧要。
  • @CrisLuengo 我总是在 Windows 上使用 'r''w',我可以看出默认是二进制的。我很久以前申请'rb''wb',但是在阅读文档后,我看到所有示例都使用'r''w'(我开始使用'r''w')。
  • 很高兴知道。由于错误的 b/t 模式,我已经看到了很多错误,因此我在上面发表了评论。多年来,我一直很高兴地避免使用 Windows,所以不必再担心它了。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-20
  • 1970-01-01
  • 2016-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多