All 2 entries tagged Java

View all 243 entries tagged Java on Warwick Blogs | View entries tagged Java at Technorati | There are no images tagged Java on this blog

September 14, 2009

Using subsample averaging instead of scaling in JAI to get better results

I was looking over this press release about using parallel computing with Xboxes this morning and was struck by just how rubbish the resized images look in it. We use JAI to do image resizing in pure Java in our CMS, and obviously it’s not coming out very well. We’re turning a high quality source image into a very low quality thumbnail.

I tried fiddling with the interpolation on our operation, from Bilinear to Bicubic or Nearest-Neighbour but nothing seemed to make a noticable difference. In the end, however, I stumbled upon this which suggested using Subsample Averaging instead of Scaling as the operation in JAI. Success!


// We have sourceSS, a SeekableStream, and an OutputStream, out

// Load the image from a source stream
RenderedOp source = JAI.create("stream", sourceSS);

// scale the image
float width = source.getWidth();
float height = source.getHeight();

// assume no resizing at first
double scale = 1;

// if the image is too wide, scale down
if (shouldResizeWidth(source, maxWidth)) {
    scale = maxWidth / width;
}

// if the image is too hight, scale down
// IF that makes it smaller than maxWidth has done already
if (shouldResizeHeight(source, maxHeight)) {
    float heightScale = maxHeight / height;
    if (heightScale < scale) {
scale = heightScale;
    }
}

ParameterBlock params = new ParameterBlock();
params.addSource(source);
params.add(scale);// x scale factor
params.add(scale);// y scale factor
params.add(0.0F);// x translate
params.add(0.0F);// y translate

Map<RenderingHints.Key, Object> map = Maps.newHashMap();
map.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
map.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
map.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
map.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

RenderingHints hints = new RenderingHints(map);

params.add(interpolation);

// Here's the important bit - use "SubsampleAverage" instead of "scale" 
RenderedOp alteredImage = JAI.create("SubsampleAverage", params, hints);

ImageEncoder encoder;

switch (fileType) {
    case gif:
    case jpg:
        // now re-encode
        JPEGEncodeParam jpegEncodeParam = new JPEGEncodeParam();
        jpegEncodeParam.setQuality(DEFAULT_SAMPLING_QUALITY);
        // who knows what all this could possibly mean ?
        jpegEncodeParam.setHorizontalSubsampling(0, 1);
        jpegEncodeParam.setHorizontalSubsampling(1, 2);
        jpegEncodeParam.setHorizontalSubsampling(2, 2);
        jpegEncodeParam.setVerticalSubsampling(0, 1);
        jpegEncodeParam.setVerticalSubsampling(1, 1);
        jpegEncodeParam.setVerticalSubsampling(2, 1);
        final int restartInterval = 64;
        jpegEncodeParam.setRestartInterval(restartInterval);

        // done messing with the image. Send the bytes to the
        // outputstream.
        encoder = ImageCodec.createImageEncoder("JPEG", out, jpegEncodeParam);

        break;
    case png:
        PNGEncodeParam.RGB pngEncodeParam = new PNGEncodeParam.RGB();
        encoder = ImageCodec.createImageEncoder("PNG", out, pngEncodeParam);
        break;
    default:
        throw new IllegalArgumentException("Unrecognised image");
}

PlanarImage planarImage = alteredImage.getRendering();
encoder.encode(planarImage);

The difference is actually pretty startling.

Resized using “scale” with bicubic interpolation Resized using “SubsampleAverage”

June 30, 2009

How do programmers feel about their software?

Writing about web page http://www.natpryce.com/articles/000748.html

Nat Pryce posted an article entitled "What do Programmers Feel About Their Software?", which provided a program to try and visualise what the comments in code indicate about programmers' emotions. The program basically analyses all of the comments in the program (which are usually only seen by other programmers working on the same software) and uses Synesketch to display a visual representation of emotion.

So, naturally, I plugged in some of our own software, and the results were quite surprising... There are some demos on the Synesketch website which show some examples of what the images mean.

Blogbuilder

Blogbuilder

Surprisingly, there is a lot of happiness here (signified by circles in bright colours).

Files.Warwick

Files.Warwick

Again, strong happiness for our file-sharing application.

Our (unreleased and unnamed) portal project

Portal Project

Even stronger happiness here, which is to be expected more since it's a relatively new project and I'm the only one who's worked on it...

Sitebuilder2

Sitebuilder2

In sharp (and dire) contrast, comments in our CMS show severe sadness. There are probably a few reasons for this... use of Swing WebFlow is probably up there as one of the top reasons. There's also a LOT more code (and more programmers) than in any of the other projects, and we're a lot more likely to look at each others' code and go "wrong!"


<about />

 

I’m a Web Developer in e-lab, part of IT Services at the University of Warwick.

<input type="search" />

<ol id="recentComments">

  • First commit was around 12 months ago, but there was a long period where it was put on the back burn… by Mathew Mannion on this entry
  • So, how long did it take?! by Phil Wilson on this entry
  • Hi Matthew, having a problem putting favourites into folders, it only seems to let me put them in on… by Rupert Elder on this entry
  • I wrote one entry in Chinese. It published the content as lots of questions marks. by Hongfeng Sun on this entry
  • I'm sure there's a setting somewhere that'd filter it out. by Nick on this entry

<ol id="archive">

Loading…

Am I still fat?

Not signed in
Sign in

Powered by BlogBuilder
© MMXVII