Java의 JPEG 이미지에 DPI 메타 데이터를 작성하십시오
-
04-07-2019 - |
문제
JPEG 이미지의 DPI 메타 데이터를 Java로 프로그래밍 방식으로 설정하려고합니다. 이미지의 소스는 스캐너이므로 이미지 원시 데이터와 함께 Twain의 수평/수직 해상도를 얻습니다. 더 나은 인쇄 결과를 위해이 정보를 저장하고 싶습니다.
지금까지 내가 가지고있는 코드는 다음과 같습니다. 원시 이미지 (BytearRay)를 JPEG 파일에 저장하지만 iiometadata를 통해 지정할 x/ydensity 정보를 무시합니다. 내가 잘못하고있는 조언이 있습니까?
다른 솔루션 (타사 라이브러리 등)도 환영합니다.
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream
import org.w3c.dom.Element;
import com.sun.imageio.plugins.jpeg.JPEGImageWriter;
public boolean saveJpeg(int[] byteArray, int width, int height, int dpi, String file)
{
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
WritableRaster wr = bufferedImage.getRaster();
wr.setPixels(0, 0, width, height, byteArray);
try
{
// Image writer
JPEGImageWriter imageWriter = (JPEGImageWriter) ImageIO.getImageWritersBySuffix("jpeg").next();
ImageOutputStream ios = ImageIO.createImageOutputStream(new File(file));
imageWriter.setOutput(ios);
// Compression
JPEGImageWriteParam jpegParams = (JPEGImageWriteParam) imageWriter.getDefaultWriteParam();
jpegParams.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
jpegParams.setCompressionQuality(0.85f);
// Metadata (dpi)
IIOMetadata data = imageWriter.getDefaultImageMetadata(new ImageTypeSpecifier(bufferedImage), jpegParams);
Element tree = (Element)data.getAsTree("javax_imageio_jpeg_image_1.0");
Element jfif = (Element)tree.getElementsByTagName("app0JFIF").item(0);
jfif.setAttribute("Xdensity", Integer.toString(dpi));
jfif.setAttribute("Ydensity", Integer.toString(dpi));
jfif.setAttribute("resUnits", "1"); // density is dots per inch
// Write and clean up
imageWriter.write(data, new IIOImage(bufferedImage, null, null), jpegParams);
ios.close();
imageWriter.dispose();
}
catch (Exception e)
{
return false;
}
return true;
}
감사!
해결책
여기서 고려되지 않은 일부 문제 :
트리는 iometadata에 직접 매핑되지 않습니다. 트리에서 데이터를 적용하려면 밀도 및 래스터 매개 변수를 설정 한 후 다음 호출을 추가하십시오.
data.setFromTree("javax_imageio_jpeg_image_1.0", tree);
메타 데이터를 쓰기 호출에서 첫 번째 매개 변수로 사용하지 마십시오. 보다
JPEGImageWriter#write(IIOMetaData, IIOImage, ImageWriteParam)
. StreamMetadata가 NULL이 아닌 경우 경고 (warment_stream_metadata_ignored)가 생성됩니다.메타 데이터를 다음과 같이 설정하십시오
IOMetadata
의IOImage
. 이 메타 데이터는 jpegimagewriter가 사용합니다. 그런 다음 올바른 쓰기 호출입니다imageWriter.write(null, new IIOImage(F_scaledImg, null, data), jpegParams);
다른 팁
나는 이것이 버그 일 수있을 것 같다.
이 게시물을 찾았습니다 몇 가지 Google 검색에서
분명히 버그를 가리키는 것이 더 많이 있습니다.
위의 게시물은 Jmagick을 제 3 자로 사용하는 것에 대해 이야기합니다.