我要求客户以.JIF格式(JFIF)发送图像。我有java应用程序,但我不能google anithing如何转换为该图像类型的主题,我甚至可以很难google anithing to" .JIF"格式化本身。
已编辑: 有人可以建议如何在java中将Exif图像转换为JFIF吗?以及如何为此JFIF图像添加coments? (试图使用jheader库遗憾地以nullpointer异常结束,在google上没有更多的选择。)
答案 0 :(得分:1)
首先,您需要阅读该图像,然后您必须将该图像写入您想要的尺寸和格式。 您必须使用 ImageIO 类和 BufferedReader 来读取图像 要编写它们,请使用 Graphics2D 类 将格式名称替换为 jif
File inputFile = new File(inputImagePath);
BufferedImage inputImage = ImageIO.read(inputFile);
// creates output image
BufferedImage outputImage = new BufferedImage(scaledWidth,
scaledHeight, inputImage.getType());
// scales the input image to the output image
Graphics2D g2d = outputImage.createGraphics();
g2d.drawImage(inputImage, 0, 0, scaledWidth, scaledHeight, null);
g2d.dispose();
// extracts extension of output file
String formatName = outputImagePath.substring(outputImagePath
.lastIndexOf(".") + 1);
// writes to output file
ImageIO.write(outputImage, formatName, new File(outputImagePath));
答案 1 :(得分:1)
编辑:将Exif JPEG转换为JFIF JPEG:
如果您不介意失去一些质量(由于有损JPEG重新编码),您可以将图像转换为:
File inFile = ...;
File outFile = ...; // Feel free to use ".jif" as extension
if (!ImageIO.write(ImageIO.read(inFile), "JPEG", outFile)) {
System.err.println("Could not write JPEG format"); // Should never happen
}
这样可行,因为默认的JPEGImageWriter
插件仅支持JFIF格式。而且因为我们没有阅读元数据,旧的Exif信息就会丢失。但是,这样做不会允许您添加注释。
要添加注释,您仍然可以使用标准的ImageIO API,但我们必须访问元数据,使代码更加冗长。有关元数据格式的更多信息,请参阅JPEG Metadata Format Specification。如果您需要转换Exif元数据中的注释,请更新您的问题,因为它需要进一步解析元数据和当前不在ImageIO API中的额外支持。
File inFile = ...;
File outFile = ...; // Feel free to use ".jif" as extension
BufferedImage image = ImageIO.read(inFile);
ImageWriter jpegWriter = ImageIO.getImageWritersByFormatName("JPEG").next(); // Should be a least one
// To write comments, we need to add it to the metadata
ImageWriteParam param = jpegWriter.getDefaultWriteParam();
IIOMetadata metadata = jpegWriter.getDefaultImageMetadata(ImageTypeSpecifier.createFromRenderedImage(image), param);
IIOMetadataNode root = (IIOMetadataNode) metadata.getAsTree("javax_imageio_jpeg_image_1.0");
IIOMetadataNode markerSequence = (IIOMetadataNode) root.getElementsByTagName("markerSequence").item(0); // Should be only one
// Insert a "COM" marker, with our comment
IIOMetadataNode com = new IIOMetadataNode("com");
com.setAttribute("comment", "Hello JFIF!");
markerSequence.appendChild(com);
// Merge edited metadata
metadata.mergeTree("javax_imageio_jpeg_image_1.0", root);
ImageOutputStream output = ImageIO.createImageOutputStream(outFile);
try {
jpegWriter.setOutput(output);
// Write image along with metadata
jpegWriter.write(new IIOImage(image, null, metadata));
}
finally {
output.close();
}
jpegWriter.dispose();
这样,我们仍然会在有损JPEG中重新编码图像,但我们将从Exif转换为JFIF并添加注释。
现在,还有另一种选择,完全无损。但它确实需要对JIF段结构有更深入的了解,以及Exif和JFIF格式如何工作。不幸的是,没有标准的Java API(我知道)这样做,所以你必须自己动手。随意使用我的JPEG segment parsing code作为起点。您链接的JHeader项目看起来非常有前景,但我对此库没有任何经验,因此我无法在那里提供任何建议。
以下是基本想法:
0xffd8
)从理论上讲,这应该有效。您可能会遇到一些较小的色彩空间问题,因为Exif数据可能包含不同的色彩空间(通常为sRGB或AdobeRGB1998),而JFIF doesn't have a defined color space。如果需要,可以添加APP2 /" ICC_PROFILE"具有所需配置文件的段(在步骤3之后)。
祝你好运! : - )注意:这不是一个完整的答案,而是试图澄清为什么你需要与你的客户交谈,并弄清楚你的JPEG有什么问题以及他实际意味着什么" JIF"
首先, JPEG不是文件格式。 JPEG是静止图像压缩标准。该标准的一部分(通常称为"附件B")是交换格式的描述,有时称为JIF。该标准还指定了一种称为SPIFF的完整文件格式,但这种格式并不是很普遍(我不认为这是你想要的)。
您到处找到的文件,称为" JPEG文件" (我认为这就是你所说的" Classic JPEG"),通常是两种略有不同的基本相同的文件格式之一:
最基本的格式是JFIF。这种格式以SOI标记开始,紧接着是带有" JFIF"的APP0标记。 (以null结尾)作为其标识符。根据{{3}}" JPEG文件交换格式与标准JPEG交换格式完全兼容; 唯一的附加要求是在SOI之后强制存在APP0标记。标记#&34; (此部分不在规范的original JFIF specification和ISO版本中,但仍然适用)。简而言之,JFIF将JPEG数据约束为1或3个分量,编码为Y或YCbCr,并强烈推荐基线DCT,霍夫曼编码压缩。
另一种常见格式是ITU。这种格式以SOI标记开始,紧接着是带有" Exif"的APP1标记。 (以null结尾)作为其标识符。这种格式由数码相机制造商开发,并允许在文件中记录更丰富的元数据(以TIFF元数据结构的形式)。根据我的理解,Exif将JPEG数据限制为3个组件,编码为YCbCr,使用基线DCT,霍夫曼编码压缩(最后一部分可能只是一个互操作性推荐,规范中的语言有点难以阅读。 ..)。
这两种格式都包含相同的"段"布局和图像数据是兼容的,但由于要求他们的"标记作为流中的第一个段(因此,还存在"第三个"格式,这是兼容性的JFIF,但仍包含用于更丰富的元数据的Exif段)。
另一个" JPEG文件系列"缺少JFIF和Exif标记,但仍遵循相同的分段布局,SOI,APPn标记,SOF,DHT,DQT,SOS和EOI标记,如附录B" (JIF)。大多数解码器也会对这些图像进行解码。
TL; DR:总结一下,所有" JPEG"文件格式有一个共同点,就是它们使用JPEG压缩,并遵循JIF结构。因此,通过将经典JPEG转换为JIF"
,有点难以理解某人的意思。" Classic JPEG" 是 JIF。