【问题标题】:Black pixels not coming completely black?黑色像素不会完全变黑?
【发布时间】:2012-01-09 10:50:59
【问题描述】:

所以我正在尝试制作仅包含黑白像素的图像。我的问题是,当我放大并查看时,我可以看到黑色周围的一些灰色像素,作为白色的一种过渡类型。这是如何/为什么会发生的?

这是生成图像的代码:

public class DrawByPixelData extends JPanel{

Image img;

public DrawByPixelData(){

    int w = 10;
    int h = 10;

    int pixels[] = new int[w*h];

    for(int i=0;i<w*h;i++){
        if(i%7==0)
            pixels[i]=0xff000000;
            else
            pixels[i]=0xffffffff;
    }

    img = createImage(new MemoryImageSource(w,h,pixels,0,w));

}

public void paintComponent(Graphics g){

    g.drawImage(img,0,0,this);
}

public void saveTheImage(){

    SaveImageData sv = new SaveImageData();
    sv.SaveImage(img);
 }

还有保存图片的代码:

public class SaveImageData {

public void SaveImage(Image img){

    BufferedImage image = toBufferedImage(img);
    save(image, "jpg");
}

private BufferedImage toBufferedImage(Image img) {

    int w = img.getWidth(null);
    int h = img.getHeight(null);

    int type = BufferedImage.TYPE_BYTE_BINARY;
    BufferedImage dest = new BufferedImage(w,h,type);
    Graphics2D g2 = dest.createGraphics();
    g2.drawImage(img, 0, 0, null);
    g2.dispose();

    return dest;
}

private static void save(BufferedImage bi, String ext){

    String fileName = "New";
    File file = new File(fileName+"."+ext);

    try {
        ImageIO.write(bi, ext, file);
    } catch (IOException e) {
        System.out.println("Image didn't write: "+e.getMessage());
        e.printStackTrace();
    }       
}

是因为我保存的格式吗?还是某种颜色模型的东西?

这是生成的图像。您也可以看到灰色像素。

谢谢。

更改为png并关闭抗锯齿后的图像:

【问题讨论】:

  • 您看到那个小图像中的灰色像素,还是在浏览器中放大它时?
  • 好的,所以在编辑软件中打开,并使用抗锯齿和减少损失的格式,我能够看到它们应该的像素,是的。

标签: java image java-2d pixels


【解决方案1】:

浏览器在缩放时会自动应用抗锯齿:这不是图像的问题,只是您以错误的方式可视化它。

尝试在 Photoshop 或 GIMP 等图像编辑器中打开它。不应出现灰色像素。

【讨论】:

  • 所以你的意思是即使我使用Windows图片查看器,它也会自动应用它?
  • JPG 中确实有一些灰色像素。不过,不是 PNG,这确实是他使用的查看器。
  • 是的,JPEG 格式也会应用噪音,因为它是一种有损格式,但我们已经解决了这个问题。
【解决方案2】:

我能想到可能发生的两件事:抗锯齿和 JPEG 有损伪像。

  1. Anti-aliasing 是您通过在两种颜色之间绘制中间像素来柔化颜色之间的边界的地方。

  2. JPEG images 通常是有损,这意味着它们已被压缩,并且压缩可以很好地消除锯齿边界以使它们不那么明显。

我没有立即在您的代码中看到任何有意进行抗锯齿的内容(这通常是一种有用的技术),但我不确定Graphics2D 默认值是什么,因此您可能想检查一下明确关闭抗锯齿(参见the documentation page 顶部的讨论)。保存时,请考虑保存为 GIF 或 PNG,它们是无损格式。

【讨论】:

  • 有什么方法可以防止抗锯齿的发生吗?还是只是格式?
  • @Achint:我刚刚编辑了答案,我不确定Graphics2D 的默认值是什么,因此您可能希望使用setRenderingHint 显式关闭抗锯齿功能。但我想你还是会想使用 GIF 或 PNG,因为 JPG 的有损性。
  • 嘿,谢谢!但是应用这些东西并没有明显的区别。会不会是别的东西?没有什么方法可以制作清晰的像素吗?
  • @Achint:你能发布生成的 GIF 或 PNG 吗?
  • @Achint:我在您上传的 PNG 文件中看不到任何抗锯齿功能。它可能是您用来放大它的工具。我正在使用 GIMP,在 1600% 的放大倍数下,我看不到任何灰色像素(我确实在 JPG 中看到了一些 - 不是很多)。
【解决方案3】:

这是因为您将图像写入为 JPEG 文件,这是一种有损格式。它的压缩是为照片构建的,而不是为具有清晰色彩边界的图像而构建的。它的压缩会在这些边界上产生微弱的“锯齿”,这就是您所看到的。您几乎肯定需要像 PNG 这样的无损索引格式。

【讨论】:

  • 感谢您的回复。将扩展类型更改为 PNG 仍然会在放大时产生像素周围的软化。还有什么我可能做错的事情,或者可以做些什么来防止这种情况发生吗?
【解决方案4】:

我尚未通过您的代码确认,但听起来您的图像正在被抗锯齿/压缩; JPEG 编码都支持这两者。

http://en.wikipedia.org/wiki/Spatial_anti-aliasing

在计算机图形学中,抗锯齿改善了多边形边缘的外观,因此它们不是“锯齿状”,而是在屏幕上变得平滑。但是,它会导致图形卡的性能成本并使用更多的视频内存。抗锯齿级别决定了多边形边缘的平滑程度(以及它消耗的视频内存量)。

您可以在 Graphics2D 对象上启用/禁用抗锯齿:

 ig.setRenderingHint(RenderingHints.KEY_ANTIALIASING, // Anti-alias!
     RenderingHints.VALUE_ANTIALIAS_ON);

完整代码:http://www.java2s.com/Code/Java/2D-Graphics-GUI/AntiAlias.htm

我还建议您将文件输出为 PNG 以确保 JPEG 压缩也不会起作用:

ImageIO.write(bi, "png", outputfile);

完整代码:http://docs.oracle.com/javase/tutorial/2d/images/saveimage.html

【讨论】:

  • 您好,感谢您的回复!关闭抗锯齿并更改为 png 不会产生任何明显的差异。有没有一种方法可以生成具有清晰像素差异的图像?
  • 如果不是抗锯齿或压缩,我不确定模糊像素是从哪里来的。
猜你喜欢
  • 1970-01-01
  • 2012-04-09
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-14
  • 1970-01-01
相关资源
最近更新 更多