001/*
002Copyright 2006 Jerry Huxtable
003
004Licensed under the Apache License, Version 2.0 (the "License");
005you may not use this file except in compliance with the License.
006You may obtain a copy of the License at
007
008   http://www.apache.org/licenses/LICENSE-2.0
009
010Unless required by applicable law or agreed to in writing, software
011distributed under the License is distributed on an "AS IS" BASIS,
012WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013See the License for the specific language governing permissions and
014limitations under the License.
015*/
016
017package com.jhlabs.image;
018
019import java.awt.*;
020import java.awt.image.*;
021
022/**
023 * A Filter to pixellate images.
024 */
025public class BlockFilter extends AbstractBufferedImageOp {
026        
027        private int blockSize = 2;
028
029    /**
030     * Construct a BlockFilter.
031     */
032        public BlockFilter() {
033        }
034
035    /**
036     * Construct a BlockFilter.
037         * @param blockSize the number of pixels along each block edge
038     */
039        public BlockFilter( int blockSize ) {
040                this.blockSize = blockSize;
041        }
042
043        /**
044         * Set the pixel block size.
045         * @param blockSize the number of pixels along each block edge
046     * @min-value 1
047     * @max-value 100+
048     * @see #getBlockSize
049         */
050        public void setBlockSize(int blockSize) {
051                this.blockSize = blockSize;
052        }
053
054        /**
055         * Get the pixel block size.
056         * @return the number of pixels along each block edge
057     * @see #setBlockSize
058         */
059        public int getBlockSize() {
060                return blockSize;
061        }
062
063    public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
064        int width = src.getWidth();
065        int height = src.getHeight();
066                int type = src.getType();
067                WritableRaster srcRaster = src.getRaster();
068
069        if ( dst == null )
070            dst = createCompatibleDestImage( src, null );
071
072                int[] pixels = new int[blockSize * blockSize];
073        for ( int y = 0; y < height; y += blockSize ) {
074            for ( int x = 0; x < width; x += blockSize ) {
075                int w = Math.min( blockSize, width-x );
076                int h = Math.min( blockSize, height-y );
077                int t = w*h;
078                getRGB( src, x, y, w, h, pixels );
079                int r = 0, g = 0, b = 0;
080                int argb;
081                int i = 0;
082                for ( int by = 0; by < h; by++ ) {
083                    for ( int bx = 0; bx < w; bx++ ) {
084                        argb = pixels[i];
085                        r += (argb >> 16) & 0xff;
086                        g += (argb >> 8) & 0xff;
087                        b += argb & 0xff;
088                        i++;
089                    }
090                }
091                argb = ((r/t) << 16) | ((g/t) << 8) | (b/t);
092                i = 0;
093                for ( int by = 0; by < h; by++ ) {
094                    for ( int bx = 0; bx < w; bx++ ) {
095                        pixels[i] = (pixels[i] & 0xff000000) | argb;
096                        i++;
097                    }
098                }
099                setRGB( dst, x, y, w, h, pixels );
100            }
101        }
102
103        return dst;
104    }
105
106        public String toString() {
107                return "Pixellate/Mosaic...";
108        }
109}
110