使用任何图像查看器/编辑器打开图像,并将其保存为“标准”格式
我不知道图像是如何创建的.我的猜测是,您已经使用了一些您所提到的“裁剪”的花哨,复杂的图像处理程序,并且该程序允许以一些不寻常的格式存储图像,并且您(或没有)修改一些在保存图像时可以使用,不知道这些选项是什么意思(如果我低估了对这里的图像格式和颜色空间的熟悉程度,则表示歉意).
然而,问题的原因是图像以YPbPr或YCbCr颜色空间的一些奇怪形式存储(我没有设法弄清楚那个,但默认情况下它们都不支持ImageIO).
我对于YPbPb-> RGB或YCbCb-> RGB的标准color conversions的尝试都没有尝试再现准确的原始颜色,但是您可能会注意到,在阅读维基百科的文章时:相当一些学术蒸气在彩色空间世界….
再次强烈建议您使用任何图像查看器/编辑器打开图像,并将其保存为“标准”格式.最好是作为PNG,因为JPG并不适合这些图像. JPG更适用于“自然”图像,如照片.对于这样的“人造”图像,压缩必须非常低以避免伪像.
然而,该程序显示的图像具有几乎正确的颜色,但颜色转换似乎还不完全正确.
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class StrangeImageTest
{
public static void main(String[] args) throws IOException
{
final BufferedImage image = readImage(new File("Ace_Diamond_1.jpg"));
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
JFrame f = new JFrame();
f.getContentPane().add(new JLabel(new ImageIcon(image)));
f.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
static BufferedImage readImage(File file) throws IOException
{
return readImage(new FileInputStream(file));
}
static BufferedImage readImage(InputStream stream) throws IOException
{
Iterator imageReaders =
ImageIO.getImageReadersBySuffix("jpg");
ImageReader imageReader = imageReaders.next();
ImageInputStream iis =
ImageIO.createImageInputStream(stream);
imageReader.setInput(iis,true,true);
Raster raster = imageReader.readRaster(0,null);
int w = raster.getWidth();
int h = raster.getHeight();
BufferedImage result =
new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
int rgb[] = new int[3];
int pixel[] = new int[3];
for (int x=0; x
{
for (int y=0; y
{
raster.getPixel(x,y,pixel);
int Y = pixel[0];
int CR = pixel[1];
int CB = pixel[2];
toRGB(Y,CB,CR,rgb);
int r = rgb[0];
int g = rgb[1];
int b = rgb[2];
int bgr =
((b & 0xFF) << 16) |
((g & 0xFF) << 8) |
(r & 0xFF);
result.setRGB(x,bgr);
}
}
return result;
}
// Based on http://www.equasys.de/colorconversion.html
private static void toRGB(int y,int cb,int cr,int rgb[])
{
float Y = y / 255.0f;
float Cb = (cb-128) / 255.0f;
float Cr = (cr-128) / 255.0f;
float R = Y + 1.4f * Cr;
float G = Y -0.343f * Cb - 0.711f * Cr;
float B = Y + 1.765f * Cb;
R = Math.min(1.0f,Math.max(0.0f,R));
G = Math.min(1.0f,G));
B = Math.min(1.0f,B));
int r = (int)(R * 255);
int g = (int)(G * 255);
int b = (int)(B * 255);
rgb[0] = r;
rgb[1] = g;
rgb[2] = b;
}
}
(注意:这可以实现得更简单,ColorConvertOp可以从用于图像的颜色空间转换为RGB颜色空间,但是如上所述,我没有想出可以使用哪个颜色空间来保存图像,即使我知道,也必须创建一个适当的ColorSpace实现.第一个websearch结果,如YCbCrColorSpace.java,不适用于给定的输入图像…)