문제

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

감사!

도움이 되었습니까?

해결책

여기서 고려되지 않은 일부 문제 :

  1. 트리는 iometadata에 직접 매핑되지 않습니다. 트리에서 데이터를 적용하려면 밀도 및 래스터 매개 변수를 설정 한 후 다음 호출을 추가하십시오.

    data.setFromTree("javax_imageio_jpeg_image_1.0", tree);
    
  2. 메타 데이터를 쓰기 호출에서 첫 번째 매개 변수로 사용하지 마십시오. 보다 JPEGImageWriter#write(IIOMetaData, IIOImage, ImageWriteParam). StreamMetadata가 NULL이 아닌 경우 경고 (warment_stream_metadata_ignored)가 생성됩니다.

  3. 메타 데이터를 다음과 같이 설정하십시오 IOMetadataIOImage. 이 메타 데이터는 jpegimagewriter가 사용합니다. 그런 다음 올바른 쓰기 호출입니다

    imageWriter.write(null, new IIOImage(F_scaledImg, null, data), jpegParams);
    

다른 팁

나는 이것이 버그 일 수있을 것 같다.

이 게시물을 찾았습니다 몇 가지 Google 검색에서

분명히 버그를 가리키는 것이 더 많이 있습니다.

위의 게시물은 Jmagick을 제 3 자로 사용하는 것에 대해 이야기합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top