From 412c7701c39e48f6802a98764df577a39a53dc78 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Fri, 24 Jan 2003 22:54:08 +0000 Subject: [PATCH] Modified image tracing not to depend on band format but to have the image convert whatever its internal format is into ARGB for our inspection. It's arguably a smidge slower (though we eliminated the multiple method calls per pixel to determine whether it is non-transparent), but will work with any source and destination image format. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2220 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../com/threerings/media/image/ImageUtil.java | 65 +++++++------------ 1 file changed, 24 insertions(+), 41 deletions(-) diff --git a/src/java/com/threerings/media/image/ImageUtil.java b/src/java/com/threerings/media/image/ImageUtil.java index efb6fa20b..38ade4354 100644 --- a/src/java/com/threerings/media/image/ImageUtil.java +++ b/src/java/com/threerings/media/image/ImageUtil.java @@ -1,5 +1,5 @@ // -// $Id: ImageUtil.java,v 1.28 2003/01/24 21:48:14 mdb Exp $ +// $Id: ImageUtil.java,v 1.29 2003/01/24 22:54:08 mdb Exp $ package com.threerings.media.image; @@ -258,21 +258,15 @@ public class ImageUtil ImageManager imgr, BufferedImage src, Color tcolor, int thickness, float startAlpha, float endAlpha) { - Raster srcdata = src.getData(); - int wid = src.getWidth(), hei = src.getHeight(); - // create the destination image + int wid = src.getWidth(), hei = src.getHeight(); BufferedImage dest = imgr.createImage( wid, hei, Transparency.TRANSLUCENT); // prepare various bits of working data - int srcTrans = src.getColorModel().getTransparency(); - int[] tpixel = new int[] { - tcolor.getRed(), tcolor.getGreen(), tcolor.getBlue(), - (int)(startAlpha * 255)}; - int[] curpixel = new int[4]; - int[] workpixel = new int[4]; - WritableRaster destdata = dest.getRaster(); + int spixel = (tcolor.getRGB() & RGB_MASK); + int salpha = (int)(startAlpha * 255); + int tpixel = (spixel | (salpha << 24)); boolean[] traced = new boolean[wid * hei]; int stepAlpha = (thickness <= 1) ? 0 : (int)(((startAlpha - endAlpha) * 255) / (thickness - 1)); @@ -290,28 +284,24 @@ public class ImageUtil // clear out the array of pixels traced this go-around Arrays.fill(traced, false); // use the destination image as our new source - srcdata = dest.getData(); + src = dest; // decrement the trace pixel alpha-level - tpixel[3] = Math.max(0, tpixel[3] - stepAlpha); + salpha -= Math.max(0, stepAlpha); + tpixel = (spixel | (salpha << 24)); } for (int yy = 0; yy < hei; yy++) { for (int xx = 0; xx < wid; xx++) { // get the pixel we're checking - srcdata.getPixel(xx, yy, curpixel); + int argb = src.getRGB(xx, yy); - if (!isTransparentPixel(curpixel)) { + if ((argb & TRANS_MASK) != 0) { // copy any pixel that isn't transparent - if (tt == 0 && srcTrans == Transparency.BITMASK) { - // give any non-transparent pixel full opacity - curpixel[3] = 255; - } - destdata.setPixel(xx, yy, curpixel); + dest.setRGB(xx, yy, argb); } else if (bordersNonTransparentPixel( - srcdata, wid, hei, traced, - xx, yy, workpixel)) { - destdata.setPixel(xx, yy, tpixel); + src, wid, hei, traced, xx, yy)) { + dest.setRGB(xx, yy, tpixel); // note that we traced this pixel this pass so // that it doesn't impact other-pixel borderedness traced[(yy*wid)+xx] = true; @@ -328,8 +318,7 @@ public class ImageUtil * pixel. */ protected static boolean bordersNonTransparentPixel ( - Raster data, int wid, int hei, boolean[] traced, - int x, int y, int[] workpixel) + BufferedImage data, int wid, int hei, boolean[] traced, int x, int y) { // check the three-pixel row above the pixel if (y > 0) { @@ -338,8 +327,7 @@ public class ImageUtil continue; } - data.getPixel(rxx, y - 1, workpixel); - if (!isTransparentPixel(workpixel)) { + if ((data.getRGB(rxx, y - 1) & TRANS_MASK) != 0) { return true; } } @@ -347,16 +335,14 @@ public class ImageUtil // check the pixel to the left if (x > 0 && !traced[(y*wid)+(x-1)]) { - data.getPixel(x - 1, y, workpixel); - if (!isTransparentPixel(workpixel)) { + if ((data.getRGB(x - 1, y) & TRANS_MASK) != 0) { return true; } } // check the pixel to the right if (x < wid - 1 && !traced[(y*wid)+(x+1)]) { - data.getPixel(x + 1, y, workpixel); - if (!isTransparentPixel(workpixel)) { + if ((data.getRGB(x + 1, y) & TRANS_MASK) != 0) { return true; } } @@ -368,8 +354,7 @@ public class ImageUtil continue; } - data.getPixel(rxx, y + 1, workpixel); - if (!isTransparentPixel(workpixel)) { + if ((data.getRGB(rxx, y + 1) & TRANS_MASK) != 0) { return true; } } @@ -378,14 +363,6 @@ public class ImageUtil return false; } - /** - * Returns whether the given pixel is completely transparent. - */ - protected static boolean isTransparentPixel (int[] pixel) - { - return (pixel[3] == 0); - } - /** * Create an image using the alpha channel from the first and the RGB * values from the second. @@ -595,4 +572,10 @@ public class ImageUtil /** The graphics configuration for the default screen device. */ protected static GraphicsConfiguration _gc; + + /** Used when seeking fully transparent pixels for outlining. */ + protected static final int TRANS_MASK = (0xFF << 24); + + /** Used when outlining. */ + protected static final int RGB_MASK = 0x00FFFFFF; }