开发者

Fastest way to load thumbnail pixel values into Java

I need to be able to load RGB pixel values at a certain resolution into Java. That resolution is small (~300x300).

Currently, I've been loading them like this:

File file = new File("...path...");     
BufferedImage imsrc = ImageIO.read(file);
int width = imsrc.getWidth();
int height = imsrc.getHeight();     
int[] data = new int[width * height];       
imsrc.getRGB(0,0, width, height, data, 0, width);

and then downsizing it myself.

Sam asked for the down-sizing code, so here it is:

/**
 * DownSize an image. 
 * This is NOT precise, and is noisy. 
 * However, this is fast and better than NearestNeighbor
 * @param pixels - _RGB pixel values for the original image
 * @param width - width of the original image
 * @param newWidth - width of the new image
 * @param newHeight - 开发者_Python百科height of the new image
 * @return - _RGB pixel values of the resized image
 */
public static int[] downSize(int[] pixels, int width, int newWidth, int newHeight) {
    int height = pixels.length / width;
    if (newWidth == width && height == newHeight) return pixels;
    int[] resized = new int[newWidth * newHeight];
    float x_ratio = (float) width / newWidth;
    float y_ratio = (float) height / newHeight;
    float xhr = x_ratio / 2;
    float yhr = y_ratio / 2;
    int i, j, k, l, m;
    for (int x = 0; x < newWidth; x ++)
        for (int y = 0; y < newHeight; y ++) {              
            i = (int) (x * x_ratio);
            j = (int) (y * y_ratio);
            k = (int) (x * x_ratio + xhr);
            l = (int) (y * y_ratio + yhr);
            for (int p = 0; p < 3; p ++) {
                m = 0xFF << (p * 8);
                resized[x + y * newWidth] |= (
                        (pixels[i + j * width] & m) +
                        (pixels[k + j * width] & m) +
                        (pixels[i + l * width] & m) + 
                        (pixels[k + l * width] & m) >> 2) & m;
            }
        }
    return resized;
}

Recently, I realized that I can down-size with ImageMagick's 'convert' and then load the down-sized version that way. This saves additional 33%.

I was wondering, if there's an even better way.

EDIT: I realized that some people would wonder if my code is good in general, and the answer is NO. The code I used works well for me, because I down-size already small images (say 640x480, otherwise .getRGB() takes forever) and I don't care if a couple of color points spill over (carry-over from addition), and I know some people really care about that.


Here's a very good article on generating thumbnails in Java in an optimal way:

http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html

You may have better results with specifying different scaling/rendering parameters.

    Graphics2D g2 = (Graphics2D)g;
    int newW = (int)(originalImage.getWidth() * xScaleFactor);
    int newH = (int)(originalImage.getHeight() * yScaleFactor);
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                        RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
    g2.drawImage(originalImage, 0, 0, newW, newH, null);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜