目录
要使用某一标准图形文件格式从 MATLAB® 工作区导出数据,使用 imwrite 函数。使用此函数,可以以诸如带标记的图像文件格式 (TIFF)、联合图像专家组 (JPEG) 和可移植网络图形 (PNG) 格式导出数据。有关所支持格式的完整列表,可以参考 imwrite 函数。
以下示例将一个 uint8 数据的多维数组 I 从 MATLAB 工作区写入一个 TIFF 格式的文件。写入该文件的输出图像的类取决于指定的格式。对于大多数格式,如果输入数组为 uint8 类,则 imwrite 将以 8 位值输出数据。
whos I
Name Size Bytes Class
I 650x600x3 1170000 uint8 array
Grand total is 1170000 elements using 1170000 bytes
imwrite(I, 'my_graphics_file.tif','tif');
注意:imwrite 支持对多种标准格式使用不同语法。例如,对于 TIFF 文件格式,您可以指定 MATLAB 用于存储图像的压缩类型。
将图像数据和元数据导出到 TIFF 文件
虽然可以使用 imwrite 将图像数据和元数据(标记)导出到带标记的图像文件格式 (TIFF) 文件,但此函数有一些限制。例如,当要修改文件中的图像数据或元数据时,必须将所有数据写入文件。不能只写入更新的部分。使用 Tiff 对象,可以写入部分图像数据,并修改单个标记或将其添加到 TIFF 文件。构造的 Tiff 对象表示与 TIFF 文件的连接,并提供对 LibTIFF 库中的众多例程的访问。
以下各节提供了使用 Tiff 对象方法和属性来执行关于 TIFF 文件的一些常见任务的分步示例。为充分利用 Tiff 对象,必须熟悉 TIFF 规范和技术说明。
创建新的 TIFF 文件
-
创建一些图像数据。此示例从 MATLAB 附带的 JPEG 文件中读取图像数据:
imgdata = imread('ngc6543a.jpg');
-
通过构造 Tiff 对象来创建新的 TIFF 文件,并将新文件名指定为参数。要创建文件,必须指定写入模式 ('w') 或追加模式 ('a'):
t = Tiff('myfile.tif','w');
当创建新的 TIFF 文件时,Tiff 构造函数会创建一个包含图像文件目录 (IFD) 的文件。TIFF 文件使用此 IFD 来组织与特定图像相关联的所有数据和元数据。一个 TIFF 文件可以包含多个 IFD。Tiff 对象将它创建的 IFD 设为当前 IFD。Tiff 对象方法对当前 IFD 进行操作。可以使用 Tiff 对象方法在 TIFF 文件中的各 IFD 之间导航并指定哪个 IFD 是当前 IFD。
-
使用 Tiff 对象的 setTag 方法设置所需的 TIFF 标记。这些所需的标记指定图像的相关信息,如长度和宽度。要将图像数据分割为条带,请指定 RowsPerStrip 标记的值。要将图像数据分割为图块,请指定 TileWidth 和 TileLength 标记的值。以下示例创建一个包含标记名称和值的结构体,并将其传递给 setTag。还可以单独设置每个标记。
tagstruct.ImageLength = size(imgdata,1); tagstruct.ImageWidth = size(imgdata,2); tagstruct.Photometric = Tiff.Photometric.RGB; tagstruct.BitsPerSample = 8; tagstruct.SamplesPerPixel = 3; tagstruct.RowsPerStrip = 16; tagstruct.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky; tagstruct.Software = 'MATLAB'; tagstruct % display tagstruct setTag(t,tagstruct)
有关支持的 TIFF 标记以及如何设置其值的信息,可以参考设置标记值。例如,Tiff 对象支持一些属性,可以用这些属性来设置某些特定属性的值。此示例使用 Tiff 对象的 PlanarConfiguration 属性为块配置指定正确的值:Tiff.PlanarConfiguration.Chunky。
-
使用 Tiff 对象的 write 方法将图像数据和元数据写入当前目录。
write(t,imgdata);
如果要将多个图像放入文件,请在执行此写入操作后立即调用 writeDirectory 方法。writeDirectory 方法在文件中设置一个新的图像文件目录,并将该新目录设为当前目录。
-
通过关闭 Tiff 对象来关闭与文件的连接:
close(t);
-
通过使用 imread 函数读取文件,然后显示图像,来测试是否创建了有效的 TIFF 文件:
imagesc(imread('myfile.tif'));
写入图像数据的条带或图块
注意:如果数据未压缩,则只能修改图像数据的一个条带或图块。
-
通过创建 Tiff 对象来打开现有的 TIFF 文件进行修改。此示例使用在创建新的 TIFF 文件中创建的文件。Tiff 构造函数返回 Tiff 对象的句柄。
t = Tiff('myfile.tif','r+');
-
生成一些数据以写入图像中的条带。此示例创建一个由零值构成的三维数组,其大小与条带大小相同。代码使用条带中的行数、图像宽度和每个像素的样本数作为维度。该数组由 uint8 值构成。
width = getTag(t,'ImageWidth'); height = getTag(t,'RowsPerStrip'); numSamples = getTag(t,'SamplesPerPixel'); stripData = zeros(height,width,numSamples,'uint8');
如果图像数据具有分块布局,则可以使用 TileWidth 和 TileLength 标记来指定维度。
-
使用 writeEncodedStrip 方法将数据写入文件中的条带。指定标识要修改的条带的索引编号。此示例选取条带 18,因为它更容易反映图像中的变化。
writeEncodedStrip(t,18,stripData);
如果图像具有分块布局,则可以使用 writeEncodedTile 方法修改图块。
-
通过关闭 Tiff 对象来关闭与文件的连接。
close(t);
-
通过使用 imread 函数读取文件,然后显示图像,来测试是否修改了 TIFF 文件中图像的条带。
modified_imgdata = imread('myfile.tif'); imagesc(modified_imgdata)
注意贯穿图像中间的黑色条带。
修改 TIFF 文件元数据(标记)
-
使用 Tiff 对象打开现有 TIFF 文件进行修改。此示例使用在创建新的 TIFF 文件中创建的文件。Tiff 构造函数返回 Tiff 对象的句柄。
t = Tiff('myfile.tif','r+');
-
使用 getTag 方法确认文件不包含 Artist 标记。此代码应该发出一条错误消息,指出它无法检索标记。
artist_value = getTag(t,'Artist');
-
使用 setTag 方法添加 Artist 标记。
setTag(t,'Artist','Pablo Picasso');
-
使用 rewriteDirectory 方法将新的标记数据写入 TIFF 文件。在修改文件中的现有元数据或向文件添加新元数据时,使用 rewriteDirectory 方法。
rewriteDirectory(t);
-
通过关闭 Tiff 对象来关闭与文件的连接。
close(t);
-
通过重新打开 TIFF 文件并使用 getTag 方法获取 Artist 标记的值来测试所做的工作。
t = Tiff('myfile.tif', 'r'); getTag(t,'Artist') ans = Pablo Picasso close(t);
创建 TIFF 文件子目录
-
创建一些图像数据。此示例从 MATLAB 附带的 JPEG 文件中读取图像数据。然后,该示例在图像数据的基础上创建两个低分辨率(缩略图)版本。
imgdata = imread('ngc6543a.jpg'); % % Reduce number of pixels by a half. img_half = imgdata(1:2:end,1:2:end,:); % % Reduce number of pixels by a third. img_third = imgdata(1:3:end,1:3:end,:);
-
通过构造 Tiff 对象来创建新的 TIFF 文件,并将新文件的名称指定为参数。要创建文件,必须指定写入模式 ('w') 或追加模式 ('a'):Tiff 构造函数返回 Tiff 对象的句柄。
t = Tiff('my_subimage_file.tif','w');
-
使用 Tiff 对象的 setTag 方法设置所需的 TIFF 标记。这些所需的标记指定图像的相关信息,如长度和宽度。要将图像数据分割为条带,请指定 RowsPerStrip 标记的值。要将图像数据分割为图块,请使用 TileWidth 和 TileLength 标记。以下示例创建一个包含标记名称和值的结构体,并将其传递给 setTag。也可以单独设置每个标记。
要创建子目录,必须设置 SubIFD 标记,指定要创建的子目录的数量。注意,指定的数字不是 SubIFD 标记的值。该数字告知 Tiff 软件创建一个指向两个子目录的 SubIFD。SubIFD 标记的实际值将是两个子目录的字节偏移量。
tagstruct.ImageLength = size(imgdata,1); tagstruct.ImageWidth = size(imgdata,2); tagstruct.Photometric = Tiff.Photometric.RGB; tagstruct.BitsPerSample = 8; tagstruct.SamplesPerPixel = 3; tagstruct.RowsPerStrip = 16; tagstruct.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky; tagstruct.Software = 'MATLAB'; tagstruct.SubIFD = 2 ; % required to create subdirectories tagstruct % display tagstruct setTag(t,tagstruct)
有关支持的 TIFF 标记以及如何设置其值的信息,可以参考设置标记值。例如,Tiff 对象支持一些属性,可以用这些属性来设置某些特定属性的值。此示例使用 Tiff 对象的 PlanarConfiguration 属性为块配置指定正确的值:Tiff.PlanarConfiguration.Chunky。
-
使用 Tiff 对象的 write 方法将图像数据和元数据写入当前目录。
write(t,imgdata);
-
通过调用 writeDirectory 方法设置第一个子目录。writeDirectory 方法设置子目录并将新目录设为当前目录。因为您指定要创建两个子目录,writeDirectory 会设置一个子目录。
writeDirectory(t);
-
设置所需的标记,就像对常规目录所做的那样。根据 LibTIFF API,子目录不能包含 SubIFD 标记。
tagstruct2.ImageLength = size(img_half,1); tagstruct2.ImageWidth = size(img_half,2); tagstruct2.Photometric = Tiff.Photometric.RGB; tagstruct2.BitsPerSample = 8; tagstruct2.SamplesPerPixel = 3; tagstruct2.RowsPerStrip = 16; tagstruct2.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky; tagstruct2.Software = 'MATLAB'; tagstruct2 % display tagstruct2 setTag(t,tagstruct2)
-
使用 Tiff 对象的 write 方法将图像数据和元数据写入子目录。
write(t,img_half);
-
通过调用 writeDirectory 方法设置第二个子目录。writeDirectory 方法设置子目录并将其设为当前目录。
writeDirectory(t);
-
设置所需的标记,就像对任何目录所做的那样。根据 LibTIFF API,子目录不能包含 SubIFD 标记。
tagstruct3.ImageLength = size(img_third,1); tagstruct3.ImageWidth = size(img_third,2); tagstruct3.Photometric = Tiff.Photometric.RGB; tagstruct3.BitsPerSample = 8; tagstruct3.SamplesPerPixel = 3; tagstruct3.RowsPerStrip = 16; tagstruct3.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky; tagstruct3.Software = 'MATLAB'; tagstruct3 % display tagstruct3 setTag(t,tagstruct3)
-
使用 Tiff 对象的 write 方法将图像数据和元数据写入子目录:
write(t,img_third);
-
通过关闭 Tiff 对象来关闭与文件的连接:
close(t);