⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 areaaveragingscalefilter.java

📁 JAVA基本类源代码,大家可以学习学习!
💻 JAVA
字号:
/* * @(#)AreaAveragingScaleFilter.java	1.14 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package java.awt.image;import java.awt.image.ImageConsumer;import java.awt.image.ColorModel;import java.util.Hashtable;import java.awt.Rectangle;/** * An ImageFilter class for scaling images using a simple area averaging * algorithm that produces smoother results than the nearest neighbor * algorithm. * <p>This class extends the basic ImageFilter Class to scale an existing * image and provide a source for a new image containing the resampled * image.  The pixels in the source image are blended to produce pixels * for an image of the specified size.  The blending process is analogous * to scaling up the source image to a multiple of the destination size * using pixel replication and then scaling it back down to the destination * size by simply averaging all the pixels in the supersized image that * fall within a given pixel of the destination image.  If the data from * the source is not delivered in TopDownLeftRight order then the filter * will back off to a simple pixel replication behavior and utilize the * requestTopDownLeftRightResend() method to refilter the pixels in a * better way at the end. * <p>It is meant to be used in conjunction with a FilteredImageSource * object to produce scaled versions of existing images.  Due to * implementation dependencies, there may be differences in pixel values  * of an image filtered on different platforms. * * @see FilteredImageSource * @see ReplicateScaleFilter * @see ImageFilter * * @version	1.14 01/23/03 * @author 	Jim Graham */public class AreaAveragingScaleFilter extends ReplicateScaleFilter {    private static final ColorModel rgbmodel = ColorModel.getRGBdefault();    private static final int neededHints = (TOPDOWNLEFTRIGHT					    | COMPLETESCANLINES);    private boolean passthrough;    private float reds[], greens[], blues[], alphas[];    private int savedy;    private int savedyrem;    /**     * Constructs an AreaAveragingScaleFilter that scales the pixels from     * its source Image as specified by the width and height parameters.     * @param width the target width to scale the image     * @param height the target height to scale the image     */    public AreaAveragingScaleFilter(int width, int height) {	super(width, height);    }    /**     * Detect if the data is being delivered with the necessary hints     * to allow the averaging algorithm to do its work.     * <p>     * Note: This method is intended to be called by the      * <code>ImageProducer</code> of the <code>Image</code> whose      * pixels are being filtered.  Developers using     * this class to filter pixels from an image should avoid calling     * this method directly since that operation could interfere           * with the filtering operation.       * @see ImageConsumer#setHints     */    public void setHints(int hints) {	passthrough = ((hints & neededHints) != neededHints);	super.setHints(hints);    }    private void makeAccumBuffers() {	reds = new float[destWidth];	greens = new float[destWidth];	blues = new float[destWidth];	alphas = new float[destWidth];    }    private int[] calcRow() {	float origmult = ((float) srcWidth) * srcHeight;	if (outpixbuf == null || !(outpixbuf instanceof int[])) {	    outpixbuf = new int[destWidth];	}	int[] outpix = (int[]) outpixbuf;	for (int x = 0; x < destWidth; x++) {            float mult = origmult;	    int a = Math.round(alphas[x] / mult);            if (a <= 0) {                a = 0;            } else if (a >= 255) {                a = 255;            } else {                // un-premultiply the components (by modifying mult here, we                // are effectively doing the divide by mult and divide by                // alpha in the same step)                mult = alphas[x] / 255;            }	    int r = Math.round(reds[x] / mult);	    int g = Math.round(greens[x] / mult);	    int b = Math.round(blues[x] / mult);	    if (r < 0) {r = 0;} else if (r > 255) {r = 255;}	    if (g < 0) {g = 0;} else if (g > 255) {g = 255;}	    if (b < 0) {b = 0;} else if (b > 255) {b = 255;}	    outpix[x] = (a << 24 | r << 16 | g << 8 | b);	}	return outpix;    }    private void accumPixels(int x, int y, int w, int h,			     ColorModel model, Object pixels, int off,			     int scansize) {	if (reds == null) {	    makeAccumBuffers();	}	int sy = y;	int syrem = destHeight;	int dy, dyrem;	if (sy == 0) {	    dy = 0;	    dyrem = 0;	} else {	    dy = savedy;	    dyrem = savedyrem;	}	while (sy < y + h) {	    int amty;	    if (dyrem == 0) {		for (int i = 0; i < destWidth; i++) {		    alphas[i] = reds[i] = greens[i] = blues[i] = 0f;		}		dyrem = srcHeight;	    }	    if (syrem < dyrem) {		amty = syrem;	    } else {		amty = dyrem;	    }	    int sx = 0;	    int dx = 0;	    int sxrem = 0;	    int dxrem = srcWidth;	    float a = 0f, r = 0f, g = 0f, b = 0f;	    while (sx < w) {		if (sxrem == 0) {		    sxrem = destWidth;		    int rgb;		    if (pixels instanceof byte[]) {			rgb = ((byte[]) pixels)[off + sx] & 0xff;		    } else {			rgb = ((int[]) pixels)[off + sx];		    }                    // getRGB() always returns non-premultiplied components		    rgb = model.getRGB(rgb);		    a = rgb >>> 24;		    r = (rgb >> 16) & 0xff;		    g = (rgb >>  8) & 0xff;                    b = rgb & 0xff;                    // premultiply the components if necessary                    if (a != 255.0f) {                        float ascale = a / 255.0f;                        r *= ascale;                        g *= ascale;                        b *= ascale;                    }		}		int amtx;		if (sxrem < dxrem) {		    amtx = sxrem;		} else {		    amtx = dxrem;		}		float mult = ((float) amtx) * amty;		alphas[dx] += mult * a;		reds[dx] += mult * r;		greens[dx] += mult * g;		blues[dx] += mult * b;		if ((sxrem -= amtx) == 0) {		    sx++;		}		if ((dxrem -= amtx) == 0) {		    dx++;		    dxrem = srcWidth;		}	    }	    if ((dyrem -= amty) == 0) {		int outpix[] = calcRow();		do {		    consumer.setPixels(0, dy, destWidth, 1,				       rgbmodel, outpix, 0, destWidth);		    dy++;		} while ((syrem -= amty) >= amty && amty == srcHeight);	    } else {		syrem -= amty;	    }	    if (syrem == 0) {		syrem = destHeight;		sy++;		off += scansize;	    }	}	savedyrem = dyrem;	savedy = dy;    }    /**     * Combine the components for the delivered byte pixels into the     * accumulation arrays and send on any averaged data for rows of     * pixels that are complete.  If the correct hints were not     * specified in the setHints call then relay the work to our     * superclass which is capable of scaling pixels regardless of     * the delivery hints.     * <p>     * Note: This method is intended to be called by the      * <code>ImageProducer</code> of the <code>Image</code>      * whose pixels are being filtered.  Developers using     * this class to filter pixels from an image should avoid calling     * this method directly since that operation could interfere     * with the filtering operation.     * @see ReplicateScaleFilter     */    public void setPixels(int x, int y, int w, int h,			  ColorModel model, byte pixels[], int off,			  int scansize) {	if (passthrough) {	    super.setPixels(x, y, w, h, model, pixels, off, scansize);	} else {	    accumPixels(x, y, w, h, model, pixels, off, scansize);	}    }    /**     * Combine the components for the delivered int pixels into the     * accumulation arrays and send on any averaged data for rows of     * pixels that are complete.  If the correct hints were not     * specified in the setHints call then relay the work to our     * superclass which is capable of scaling pixels regardless of     * the delivery hints.     * <p>     * Note: This method is intended to be called by the      * <code>ImageProducer</code> of the <code>Image</code>      * whose pixels are being filtered.  Developers using     * this class to filter pixels from an image should avoid calling     * this method directly since that operation could interfere     * with the filtering operation.     * @see ReplicateScaleFilter     */    public void setPixels(int x, int y, int w, int h,			  ColorModel model, int pixels[], int off,			  int scansize) {	if (passthrough) {	    super.setPixels(x, y, w, h, model, pixels, off, scansize);	} else {	    accumPixels(x, y, w, h, model, pixels, off, scansize);	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -