1

I working on a grails project with some image resizing using java.awt.Graphics2D. I'm doing a resize in order to have 5 sizes. The smallest size has width: 77 and height: 58. The problem is that for this size, the quality of the resized picture is really bad. I know about ImageMagic but I cannot change to it, I'm stuck with some java libraries. Here is my piece of code:

 def img = sourceImage.getScaledInstance(77, 58, Image.SCALE_SMOOTH)
 BufferedImage bimage = new BufferedImage(77, 58, BufferedImage.TYPE_INT_RGB)
 Graphics2D bGr = bimage.createGraphics()
 bGr.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY )
 bGr.drawImage(img, 0, 0, null)
 bGr.dispose()

I've tried differents hints but does not change the quality. We have an iOS app we really need to have sharp pictures. Does anybody have any idea how to improve the picture quality ?

tim_yates
  • 167,322
  • 27
  • 342
  • 338
CC.
  • 2,736
  • 11
  • 53
  • 70
  • 1
    [This might be of interest](https://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html) – tim_yates Nov 25 '13 at 14:10

1 Answers1

2

So, munging the code half way down that link into Groovy, we get:

import java.awt.image.*
import java.awt.*
import static java.awt.RenderingHints.*
import javax.imageio.*

BufferedImage getScaledInstance( image, int nw, int nh, hint ) {
    int type = ( image.getTransparency() == Transparency.OPAQUE ) ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB
    int w = image.width
    int h = image.height

    while( true ) {
        if( w > nw ) {
            w /= 2
            if( w < nw ) {
                w = nw
            }
        }
        if( h > nh ) {
            h /= 2
            if( h < nh ) {
                h = nh
            }
        }
        image = new BufferedImage( w, h, type ).with { ni ->
            ni.createGraphics().with { g ->
                g.setRenderingHint( KEY_INTERPOLATION, hint )
                g.drawImage( image, 0, 0, w, h, null )
                g.dispose()
                ni
            }
        }
        if( w == nw || h == nh ) {
            return image
        }
    }
}

def img = ImageIO.read( 'https://raw.github.com/grails/grails-core/master/media/logos/grails-logo-highres.jpg'.toURL() )
int newWidth = img.width / 20
int newHeight = img.height / 20
BufferedImage newImage = getScaledInstance( img, newWidth, newHeight, VALUE_INTERPOLATION_BILINEAR )

Which is the best I can get with Java/Groovy

tim_yates
  • 167,322
  • 27
  • 342
  • 338