gpt4 book ai didi

java - 无法使用三星手机创建的 java 加载 JPEG

转载 作者:搜寻专家 更新时间:2023-10-30 19:43:19 25 4
gpt4 key购买 nike

我在使用 javafx 加载三星 Galaxy S7 edge 拍摄的 JPEG 图像时遇到问题(图像可在 https://www.dropbox.com/s/w6lvdnqwcgw321s/20171122_140732.jpg?dl=0 获得)。我正在使用 Image 类加载图像。

import java.io.FileInputStream;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class JPEGProblem extends Application {

public static void main(String[] args) {
launch(args);
}

@Override
public void start(Stage window) throws Exception {
Image img = new Image(new FileInputStream("/path/to/image.jpg"));
if (img.getException() != null)
throw img.getException();

ImageView imgView = new ImageView(img);
window.setScene(new Scene(new Pane(imgView)));
window.show();
}

}

尝试加载图像的构造函数调用在错误流中打印以下错误消息:

Feb 04, 2018 11:48:23 PM com.sun.javafx.tk.quantum.PrismImageLoader2$PrismLoadListener imageLoadWarning WARNING: Invalid SOS parameters for sequential JPEG

我从图像对象中得到的异常是一个带有消息的 IOException:

Unsupported marker type 0x65

我做了一些研究,事实证明,这是三星手机拍摄的全景图像的一个已知问题。正如该线程中所指出的:https://forums.adobe.com/thread/2131432 , 一些 0xFF 字节,指示后续字节是元信息而不是实际数据,不会通过在 0xFF 之后添加后续 0x00 字节来转义。
然而,我尝试编写代码来处理图像数据以添加丢失的 0x00 字节,但事实证明这比预期的要复杂得多,而且我不想编写自己的 JPEG 解析器/加载器。
有一些程序可以显示那些无效的 JPEG 图像,例如微软照片或画图。他们似乎容忍了这些无效图像,将那些虚假标记视为内容数据。
有什么方法可以用 java 加载这些无效图像,而无需自己处理单个字节?

最佳答案

你的问题很棒,真的让我思考和搜索了几个小时)

这是我最终得到的一个有点老套的解决方案(没有第 3 方库):

import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
import java.awt.image.DirectColorModel;
import java.awt.image.PixelGrabber;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;

public class JPEGProblem extends Application {

public static void main(String[] args) {
launch(args);
}

@Override
public void start(Stage window) throws Exception {
BufferedImage bi = getBufferedImage();
ImageView imgView = getFinalImageView(bi);
window.setScene(new Scene(new Pane(imgView)));
window.show();
}

private BufferedImage getBufferedImage() throws InterruptedException {
final java.awt.Image image = Toolkit.getDefaultToolkit().createImage("path\to\file");

final int[] RGB_MASKS = {0xFF0000, 0xFF00, 0xFF};
final ColorModel RGB_OPAQUE =
new DirectColorModel(32, RGB_MASKS[0], RGB_MASKS[1], RGB_MASKS[2]);

PixelGrabber pg = new PixelGrabber(image, 0, 0, -1, -1, true);
pg.grabPixels();
int width = pg.getWidth(), height = pg.getHeight();
DataBuffer buffer = new DataBufferInt((int[]) pg.getPixels(), pg.getWidth() * pg.getHeight());
WritableRaster raster = Raster.createPackedRaster(buffer, width, height, width, RGB_MASKS, null);
return new BufferedImage(RGB_OPAQUE, raster, false, null);
}

private ImageView getFinalImageView(BufferedImage bi) throws Exception {
ImageView imgView = new ImageView(SwingFXUtils.toFXImage(bi, null));
imgView.setFitWidth(1024);
imgView.setFitHeight(756);
imgView.setRotate(180);
return imgView;
}
}

这里的问题是标准的 Image api 无法读取“损坏的”图像,因此我们需要以某种不同的方式读取它。为此 Toolkit.getDefaultToolkit().createImage()可以使用方法。实际上,getBufferedImage 部分取自 this answer ,所以,所有的学分都在那里)

getFinalImageView 方法中,我们简单地将此BufferedImage 转换为javafx Image,然后使用ImageIO 转换为ImageView类。

结果: enter image description here

注意!我仍然可以在日志中观察到一些异常,但它们不会阻止此代码成功执行。

关于java - 无法使用三星手机创建的 java 加载 JPEG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48653584/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com