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