Как показать 65687x70562 TIF-файл в Java - PullRequest
0 голосов
/ 27 декабря 2018

Я пытаюсь показать TIF-файл 500 МБ в графическом интерфейсе Java.

Моя проблема: Размеры (ширина = 65687, высота = 70562) слишком велики

Я уже использую JAI Libary (Codec 1.1.3 и Core 1.1.3) для загрузкифайл.

static Image load(byte[] data) throws Exception {
    Image image = null;
    SeekableStream stream = new ByteArraySeekableStream(data);
    String[] names = ImageCodec.getDecoderNames(stream);
    ImageDecoder dec = ImageCodec.createImageDecoder(names[0], stream, null);
    RenderedImage im = dec.decodeAsRenderedImage();
    image = PlanarImage.wrapRenderedImage(im).getAsBufferedImage();
    return image;
}

public static void main(String[] args) throws Exception{
    String path;
    if (args.length==0) {
      path = JOptionPane.showInputDialog(null, "Image Path",
      "c:/applications/sidebar.tif");
    }
    else {
      path = args[0];
    }
    FileInputStream in = new FileInputStream(path);
    FileChannel channel = in.getChannel();
    ByteBuffer buffer = ByteBuffer.allocate((int)channel.size());
    channel.read(buffer);
    Image image = load(buffer.array());
    // make sure that the image is not too big
    //  scale with a width of 500 
    Image imageScaled = 
      image.getScaledInstance(500, -1,  Image.SCALE_SMOOTH);
    //
    System.out.println("image: " + path + "\n" + image);
    //
    JOptionPane.showMessageDialog(null, new JLabel(
        new ImageIcon( imageScaled )) );
  }

Я просто хочу увидеть все изображение в кадре.

ОБНОВЛЕНИЕ

Сейчас я использую JAVA 11.

Но у меня возникла новая проблема

java.lang.IllegalArgumentException: width*height > Integer.MAX_VALUE! at java.desktop/javax.imageio.ImageReader.getDestination(ImageReader.java:2821) at java.desktop/com.sun.imageio.plugins.tiff.TIFFImageReader.read(TIFFImageReader.java:1141) at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1468) at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1420) at list.ImageView.<init>(ImageView.java:26) at gui.GUI_Cut.<init>(GUI_Cut.java:61) at gui.GUI_Main$3$1.run(GUI_Main.java:139) at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Мой код:

image = ImageIO.read(getClass().getResource("/images/" + filename));

Я загружаюбольшое изображение tif.

1 Ответ

0 голосов
/ 31 декабря 2018

ImageIO может считывать некоторые изображения по одной прямоугольной подобласти за раз.Каждый такой прямоугольник называется плиткой.

Я экспериментировал с несколькими изображениями в формате TIFF и обнаружил, что ImageIO хочет прочитать каждое из них как плитки.Я не знаю, гарантированно ли это так для каждого изображения TIFF.

Мы можем создать менее масштабируемое изображение, требующее памяти (используя формат ColorModel и Raster для первой плитки, с которой мы сталкиваемся), затемНарисуйте каждую плитку прямо в масштабированное изображение:

public BufferedImage readLargeImage(File file,
                                    int desiredWidth)
throws IOException {

    BufferedImage scaledImage = null;
    Graphics2D scaledImageGraphics = null;

    ImageReader tiffReader =
        ImageIO.getImageReadersByFormatName("TIFF").next();

    try (ImageInputStream stream = ImageIO.createImageInputStream(file)) {
        tiffReader.setInput(stream);

        int width = tiffReader.getWidth(0);
        int height = tiffReader.getHeight(0);

        int tileWidth = tiffReader.getTileWidth(0);
        int tileHeight = tiffReader.getTileHeight(0);

        int scaledWidth = desiredWidth;
        float scale = (float) scaledWidth / width;

        for (int tileY = 0; tileY * tileHeight < height; tileY++) {
            for (int tileX = 0; tileX * tileWidth < width; tileX++) {
                BufferedImage tile = tiffReader.readTile(0, tileX, tileY);

                if (scaledImage == null) {
                    scaledImage = new BufferedImage(
                        tile.getColorModel(),
                        tile.getRaster().createCompatibleWritableRaster(
                            scaledWidth,
                            (int) (scale * height)),
                        false, new Properties());
                    scaledImageGraphics = scaledImage.createGraphics();

                    // Optional: better scaling
                    scaledImageGraphics.setRenderingHint(
                        RenderingHints.KEY_RENDERING,
                        RenderingHints.VALUE_RENDER_QUALITY);
                    scaledImageGraphics.setRenderingHint(
                        RenderingHints.KEY_INTERPOLATION,
                        RenderingHints.VALUE_INTERPOLATION_BICUBIC);
                }

                scaledImageGraphics.drawImage(tile,
                    (int) (scale * tileX * tileWidth),
                    (int) (scale * tileY * tileHeight), 
                    (int) (scale * tileWidth),
                    (int) (scale * tileHeight),
                    null);
            }
        }
    }

    scaledImageGraphics.dispose();

    return scaledImage;
}
...