NestedCodeblocksFTW
NestedCodeblocksFTW

Reputation: 746

Java how to set jpg quality

Just wanting to get some code edited so that the output jpg quality isn't the default low quality setting that

try
        {
            ImageIO.write(var6, "jpg", var7);
        }

.....is using currently.

I've looked at some other java examples of setting quality, not being very familiar with Java I'm having trouble understanding how to plug stuff in and rework some examples, that I've seen on using Java to set image quality.

ImageWriteParam iwparam = new JPEGImageWriteParam(Locale.getDefault());
    iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    iwparam.setCompressionQuality(quality);
    writer.write(null, new IIOImage(image, null, null), iwparam);

Here is the code I'm trying to get work........

public static String func_74292_a(File par0File, String par1Str, int par2, int par3)
{
    File var4 = new File(par0File, "screenshots");
    var4.mkdir();
    int var5 = par2 * par3;

    if (field_74293_b == null || field_74293_b.capacity() < var5)
    {
        field_74293_b = BufferUtils.createIntBuffer(var5);
        field_74294_c = new int[var5];
    }

    GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, 1);
    GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
    field_74293_b.clear();
    GL11.glReadPixels(0, 0, par2, par3, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, field_74293_b);
    field_74293_b.get(field_74294_c);
    func_74289_a(field_74294_c, par2, par3);
    BufferedImage var6 = new BufferedImage(par2, par3, 1);
    var6.setRGB(0, 0, par2, par3, field_74294_c, 0, par2);

    if (par1Str == null)
    {
        var7 = func_74290_a(var4);
    }
    else
    {
        var7 = new File(var4, par1Str);
    }

    try
    {
        ImageIO.write(var6, "jpg", var7);
    }
    catch (IOException var8)
    {
        ;
    }

    Thread var7x = new Thread(new ScreenShotHelper$1());
    var7x.start();
    return "\u00a7aUploading Screenshot....";
}

private static File func_74290_a(File par0File)
{
    String var1 = dateFormat.format(new Date()).toString();
    int var2 = 1;

    while (true)
    {
        File var3 = new File(par0File, var1 + (var2 == 1 ? "" : "_" + var2) + ".jpg");

        if (!var3.exists())
        {
            return var3;
        }

        ++var2;
    }
}

Upvotes: 10

Views: 14926

Answers (3)

Hoku
Hoku

Reputation: 81

I came across a similar problem and the answer was not very clear to me, since at the time i did not have a knowledge on ImageIO, so to the people like me that came across this post i made a example.

try {
            
            //  Image to be altered 
            BufferedImage imagem = ImageIO.read(new File("c://nota.jpg"));
            
            //  The output image
            File outPutImage = new File("c://nota2.jpg");
            
            //  Encapsulate the outPut image
            ImageOutputStream  ios =  ImageIO.createImageOutputStream(outPutImage);
            
            //  List of ImageWritre's for jpeg format 
            Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpeg");
            
            //  Capture the first ImageWriter
            ImageWriter writer = iter.next();
            
            //  define the o outPut file to the write
            writer.setOutput(ios);

            //  Here you define the changes you wanna make to the image
            ImageWriteParam iwParam = writer.getDefaultWriteParam();
            iwParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            iwParam.setCompressionQuality(.90f);

            //  Compression and saving to file the altered image
            writer.write(null, new IIOImage(imagem, null, null), iwParam);
            
            writer.dispose();               
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

If you know of a easier way or you found out something wrong in my comments or code, please let me know in the comments so i can alter.

Upvotes: 2

NestedCodeblocksFTW
NestedCodeblocksFTW

Reputation: 746

Finally did it with this code ...

try
{

    ImageOutputStream  ios =  ImageIO.createImageOutputStream(var7);
    Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpeg");
    ImageWriter writer = iter.next();
    ImageWriteParam iwp = writer.getDefaultWriteParam();
    iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    iwp.setCompressionQuality(0.85f);
    writer.setOutput(ios);
    writer.write(null, new IIOImage(var6,null,null),iwp);
    writer.dispose();

    //ImageIO.write(var6, "jpg", var7);
}

Upvotes: 29

sarcan
sarcan

Reputation: 3165

You might want to elaborate on what your actual problem with the code is.

Generally speaking, the second sniplet you were using is (more or less) the correct approach:

1) ImageIO.write(...) uses default values for pretty much everything, it requires no extra configuration.

2) If you want to tweak parameters, e.g. for the compression ratio, you should instead use an ImageWriter. You can obtain a suitable writer for any format (in your case jpg) using ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg");

3) You then set the configuration parameters to be used by the writer on an instance of ImageWriteParam. You could instanciate a JPEGImageWriteParam directly, but if you're just looking to change the compression ratio it is easier to request a default instance using ImageWriteParam param = writer.getDefaultWriteParam();

4) Set the compression quality as shown in the above code snipplet, and set the compression type to explicit accordingly.

5) The call to writer.write(null, new IIOImage(image, null, null), iwparam); basically tells your writer instance to create an image without meta data or embedded thumbnails, containing nothing but your BufferedImage and using the configuration object you created in 3).

Upvotes: 7

Related Questions