当前位置: 首页 > 面试题库 >

我的批处理jpg尺寸调整器可用于彩色图像,但是灰度级图像会变色

靳高明
2023-03-14
问题内容

我的Java程序一直有问题。用于调整图像大小。您将其放到一个文件夹中并运行它,它会创建一个带有调整大小图像的新文件夹。它在颜色上效果很好,但是在灰度方面存在问题。图像被转换,但是它们变得更亮,更褪色,好像有人弄乱了曲线或水平。所有输入文件和输出文件均为sRGB色彩空间jpeg,以RGB色彩模式保存。我尝试将成千上万个50兆像素的胶片扫描转换为15兆像素或更少。任何人都可以提供的任何帮助或想法,将不胜感激。该程序的完整代码在下面,大约130行。我觉得问题可能出在toBufferedImage函数中,但我迷失了它的可能。

package jpegresize;

import java.awt.*;
import java.awt.image.*;
import java.util.*;
import java.io.*;
import javax.imageio.*;
import javax.imageio.stream.*;
import javax.swing.*;

public class Main {

public static void main(String[] args) {

    System.out.println("JPEGResize running . . .");

    int max_side = 4096;
    float quality = 0.9f;

    if(args.length == 0) System.out.println("No maximum side resolution or compression quality arguments given, using default values.\nUsage: java -jar JPEGResize.jar <maximum side resolution in pixels> <quality 0 to 100 percent>");
    if(args.length >= 1) max_side = Integer.parseInt(args[0]);
    if(args.length >= 2) quality = Float.parseFloat(args[1]) / 100.0f;

    System.out.println("Maximum side resolution: " + max_side);
    System.out.println("Compression quality: " + (quality * 100) + "%");

    File folder = new File(".");
    File[] listOfFiles = folder.listFiles(new JPEGFilter());

    for(int i = 0; i < listOfFiles.length; i++) {

        System.out.println("Processing " + listOfFiles[i].getName() + " . . .");
        resizeFile(listOfFiles[i].getName(), max_side, quality);
        System.out.println("Saved /resized/" + listOfFiles[i].getName());
    }

    System.out.println("Operations complete.");
}

public static void resizeFile(String filename, int max_side, float quality) {

    try
    {
        BufferedImage input_img = ImageIO.read(new File(filename));

        double aspect_ratio = ((double)input_img.getWidth()) / ((double)input_img.getHeight());
        int width, height;

        if(input_img.getWidth() >= input_img.getHeight()) {

            width = max_side;
            height = (int)(((double)max_side) / aspect_ratio);
        }
        else {

            width = (int)(((double)max_side) * aspect_ratio);
            height = max_side;
        }

        Image scaled_img = input_img.getScaledInstance(width, height, Image.SCALE_SMOOTH);
        BufferedImage output_img = toBufferedImage(scaled_img);

        Iterator iter = ImageIO.getImageWritersByFormatName("jpeg");
        ImageWriter writer = (ImageWriter)iter.next();
        ImageWriteParam iwp = writer.getDefaultWriteParam();
        iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        iwp.setCompressionQuality(quality);

        File doesDirExist = new File("resized/");
        if(!doesDirExist.exists())
            new File("resized").mkdir();

        File file = new File("resized/" + filename);
        FileImageOutputStream output = new FileImageOutputStream(file);
        writer.setOutput(output);
        IIOImage image = new IIOImage(output_img, null, null);
        writer.write(null, image, iwp);
        writer.dispose();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

// This method returns a buffered image with the contents of an image
public static BufferedImage toBufferedImage(Image image) {
    if (image instanceof BufferedImage) {
        return (BufferedImage)image;
    }

    // This code ensures that all the pixels in the image are loaded
    image = new ImageIcon(image).getImage();

    // Create a buffered image with a format that's compatible with the screen
    BufferedImage bimage = null;
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    try {
        // Determine the type of transparency of the new buffered image
        int transparency = Transparency.OPAQUE;

        // Create the buffered image
        GraphicsDevice gs = ge.getDefaultScreenDevice();
        GraphicsConfiguration gc = gs.getDefaultConfiguration();
        bimage = gc.createCompatibleImage(
            image.getWidth(null), image.getHeight(null), transparency);
    } catch (HeadlessException e) {
        // The system does not have a screen
    }

    if (bimage == null) {
        // Create a buffered image using the default color model
        int type = BufferedImage.TYPE_INT_RGB;
        bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
    }

    // Copy image to buffered image
    Graphics g = bimage.createGraphics();

    // Paint the image onto the buffered image
    g.drawImage(image, 0, 0, null);
    g.dispose();

    return bimage;
}
}

class JPEGFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
    return (name.toLowerCase().endsWith(".jpg")) || (name.toLowerCase().endsWith(".jpeg"));
    }
}

问题答案:

如果jdk的类和方法有错误,请将该错误报告给oracle(哦!我希望我可以继续对SUN说..)。

并且,尽管下一版本将纠正该错误;),请尝试一些变通方法,如此处所建议的那样自行缩放图像。

问候,斯特凡



 类似资料:
  • 主要内容:将彩色图像转换为灰度在前面的章节中,我们讨论了如何读取不同类型的输入图像(二进制,灰度,BGR等)。 在本章中,我们将学习如何将一种图像转换为另一种图像。 包中名为的类提供了将图像从一种颜色转换为另一种颜色的方法。 将彩色图像转换为灰度 使用方法将彩色图像转换为灰度。 以下是此方法的语法。 该方法接受以下参数 - src - 表示来源的矩阵。 dst - 表示目的地的矩阵。 code - 表示转换类型的整数代码,例如

  • 本文向大家介绍彩色图像、灰度图像、二值图像和索引图像区别?相关面试题,主要包含被问及彩色图像、灰度图像、二值图像和索引图像区别?时的应答技巧和注意事项,需要的朋友参考一下 彩色图像:RGB图像。灰度图像:0-255像素值。二值图像:0和1,用于掩膜图像。 索引图像:在灰度图像中,自定义调色板,自定义输出256种颜色值。

  • 上一节课讲解了纹理贴图的知识点,本节课通过一个把彩色图处理为灰度图的案例进一步认识可编程片元着色器和逐片元的概念。 纹理贴图可以经过渲染管线处理后映射到三维空间中顶点坐标定义的位置,在这个过程中,执行方法texture2D()提取的像素值直接赋值给片元,存入帧缓存的颜色缓冲区中, 显示系统扫描颜色缓冲区中的像素值显示在屏幕上。渲染过线的片元着色器是可编程的,可以执行着色器语言编写的程序,也就是说可

  • 本文向大家介绍在Python中使用OpenCV将彩色图像灰度化,包括了在Python中使用OpenCV将彩色图像灰度化的使用技巧和注意事项,需要的朋友参考一下 在Python中,我们可以使用一个名为cv2的OpenCV库。Python不包含cv2,因此我们需要单独安装它。 对于Windows: 对于Linux: 在下面给出的程序中,我们使用以下三个功能: imread(): 它将图像文件的绝对路径

  • 本文向大家介绍C#图像伪彩色处理方法,包括了C#图像伪彩色处理方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#图像伪彩色处理方法。分享给大家供大家参考。具体如下: 原图: 效果图: 反色图: 希望本文所述对大家的C#程序设计有所帮助。

  • 问题内容: 我正在尝试导出单色“灰度”图像中特定像素的强度值。我有一些伪代码,但是到目前为止,我还无法实现真正​​有效的功能。 问题答案: 也许这会帮助您: http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html http://docs.oracle.com/javase/7/docs/api/javax