1+ /*******************************************************************************
2+ * Filter Algorithms for Java BufferedImage
3+ * (c) 2023, Joe James
4+ *
5+ * This program loads an image file. It has methods to:
6+ * - display the image in a JPanel popup window;
7+ * - convert the image to grayscale;
8+ * - scale a grayscale image to a different size;
9+ * - pixelate a grayscale image;
10+ * - apply a Gaussian blur to a grayscale image;
11+ * - detect edges of a grayscale image;
12+ * - brighten a color image.
13+ *
14+ * These files are mainly intended to accompany my series of YouTube tutorial
15+ * videos here, https://www.youtube.com/user/joejamesusa and are mainly
16+ * intended for educational purposes. You are invited to subscribe to my
17+ * video channel, and to download and use any code in this Java
18+ * repository, according to the MIT License. Feel free to post any comments
19+ * on my YouTube channel.
20+ *
21+ * ****************************************************************************/
22+
123import java .util .*;
224import java .awt .*;
325import java .awt .image .*;
@@ -10,20 +32,25 @@ public class ImageFilter {
1032
1133 public static void main (String [] args ) {
1234 File file = new File ("photo.png" );
35+ //File file = new File("License Plate Photos/ca_10.jpeg");
1336 BufferedImage img = null ;
1437
1538 try { img = ImageIO .read (file ); }
1639 catch (IOException e ) { e .printStackTrace (System .out ); }
1740
1841 if (img != null ) {
19- //display(img);
42+ display (img );
43+ //img = brighten(img);
2044 img = toGrayScale (img );
2145 //img = toGrayScale2(img);
22- display (img );
46+ // display(img);
2347 //img = pixelate(img);
2448 //img = pixelate2(img, 3);
2549 //img = resize(img, 150);
26- img = blur (img );
50+ //img = blur(img);
51+ img = blur (blur (img ));
52+ img = heavyblur (img );
53+ img = detectEdges (img );
2754 display (img );
2855 }
2956 }
@@ -130,7 +157,7 @@ public static BufferedImage resize (BufferedImage img, int newHeight) {
130157 return scaleOp .filter (img , scaledImg );
131158 }
132159
133- // apply Gaussian blur to a grayscale image
160+ // apply 3x3 Gaussian blur to a grayscale image
134161 public static BufferedImage blur (BufferedImage img ) {
135162 BufferedImage blurImg = new BufferedImage (
136163 img .getWidth ()-2 , img .getHeight ()-2 , BufferedImage .TYPE_BYTE_GRAY );
@@ -153,6 +180,93 @@ public static BufferedImage blur (BufferedImage img) {
153180 return blurImg ;
154181 }
155182
183+ // apply 5x5 Gaussian blur to a grayscale image
184+ public static BufferedImage heavyblur (BufferedImage img ) {
185+ BufferedImage blurImg = new BufferedImage (
186+ img .getWidth ()-4 , img .getHeight ()-4 , BufferedImage .TYPE_BYTE_GRAY );
187+ int pix = 0 ;
188+ for (int y =0 ; y <blurImg .getHeight (); y ++) {
189+ for (int x =0 ; x <blurImg .getWidth (); x ++) {
190+ pix = (int )(
191+ 10 *(img .getRGB (x +3 , y +3 )& 0xFF )
192+ + 6 *(img .getRGB (x +2 , y +1 )& 0xFF )
193+ + 6 *(img .getRGB (x +1 , y +2 )& 0xFF )
194+ + 6 *(img .getRGB (x +2 , y +3 )& 0xFF )
195+ + 6 *(img .getRGB (x +3 , y +2 )& 0xFF )
196+ + 4 *(img .getRGB (x +1 , y +1 )& 0xFF )
197+ + 4 *(img .getRGB (x +1 , y +3 )& 0xFF )
198+ + 4 *(img .getRGB (x +3 , y +1 )& 0xFF )
199+ + 4 *(img .getRGB (x +3 , y +3 )& 0xFF )
200+ + 2 *(img .getRGB (x , y +1 )& 0xFF )
201+ + 2 *(img .getRGB (x , y +2 )& 0xFF )
202+ + 2 *(img .getRGB (x , y +3 )& 0xFF )
203+ + 2 *(img .getRGB (x +4 , y +1 )& 0xFF )
204+ + 2 *(img .getRGB (x +4 , y +2 )& 0xFF )
205+ + 2 *(img .getRGB (x +4 , y +3 )& 0xFF )
206+ + 2 *(img .getRGB (x +1 , y )& 0xFF )
207+ + 2 *(img .getRGB (x +2 , y )& 0xFF )
208+ + 2 *(img .getRGB (x +3 , y )& 0xFF )
209+ + 2 *(img .getRGB (x +1 , y +4 )& 0xFF )
210+ + 2 *(img .getRGB (x +2 , y +4 )& 0xFF )
211+ + 2 *(img .getRGB (x +3 , y +4 )& 0xFF )
212+ + (img .getRGB (x , y )& 0xFF )
213+ + (img .getRGB (x , y +2 )& 0xFF )
214+ + (img .getRGB (x +2 , y )& 0xFF )
215+ + (img .getRGB (x +2 , y +2 )& 0xFF ))/74 ;
216+ int p = (255 <<24 ) | (pix <<16 ) | (pix <<8 ) | pix ;
217+ blurImg .setRGB (x ,y ,p );
218+ }
219+ }
220+ return blurImg ;
221+ }
222+
223+ // detect edges of a grayscale image using Sobel algorithm
224+ // (for best results, apply blur before finding edges)
225+ public static BufferedImage detectEdges (BufferedImage img ) {
226+ int h = img .getHeight (), w = img .getWidth (), threshold =30 , p = 0 ;
227+ BufferedImage edgeImg = new BufferedImage (w , h , BufferedImage .TYPE_BYTE_GRAY );
228+ int [][] vert = new int [w ][h ];
229+ int [][] horiz = new int [w ][h ];
230+ int [][] edgeWeight = new int [w ][h ];
231+ for (int y =1 ; y <h -1 ; y ++) {
232+ for (int x =1 ; x <w -1 ; x ++) {
233+ vert [x ][y ] = (int )(img .getRGB (x +1 , y -1 )& 0xFF + 2 *(img .getRGB (x +1 , y )& 0xFF ) + img .getRGB (x +1 , y +1 )& 0xFF
234+ - img .getRGB (x -1 , y -1 )& 0xFF - 2 *(img .getRGB (x -1 , y )& 0xFF ) - img .getRGB (x -1 , y +1 )& 0xFF );
235+ horiz [x ][y ] = (int )(img .getRGB (x -1 , y +1 )& 0xFF + 2 *(img .getRGB (x , y +1 )& 0xFF ) + img .getRGB (x +1 , y +1 )& 0xFF
236+ - img .getRGB (x -1 , y -1 )& 0xFF - 2 *(img .getRGB (x , y -1 )& 0xFF ) - img .getRGB (x +1 , y -1 )& 0xFF );
237+ edgeWeight [x ][y ] = (int )(Math .sqrt (vert [x ][y ] * vert [x ][y ] + horiz [x ][y ] * horiz [x ][y ]));
238+ if (edgeWeight [x ][y ] > threshold )
239+ p = (255 <<24 ) | (255 <<16 ) | (255 <<8 ) | 255 ;
240+ else
241+ p = (255 <<24 ) | (0 <<16 ) | (0 <<8 ) | 0 ;
242+ edgeImg .setRGB (x ,y ,p );
243+ }
244+ }
245+ return edgeImg ;
246+ }
247+
248+ // brighten color image by a percentage
249+ public static BufferedImage brighten (BufferedImage img , int percentage ) {
250+ int r =0 , g =0 , b =0 , rgb =0 , p =0 ;
251+ int amount = (int )(percentage * 255 / 100 ); // rgb scale is 0-255, so 255 is 100%
252+ BufferedImage newImage = new BufferedImage (
253+ img .getWidth (), img .getHeight (), BufferedImage .TYPE_INT_ARGB );
254+ for (int y =0 ; y <img .getHeight (); y +=1 ) {
255+ for (int x =0 ; x <img .getWidth (); x +=1 ) {
256+ rgb = img .getRGB (x , y );
257+ r = ((rgb >> 16 ) & 0xFF ) + amount ;
258+ g = ((rgb >> 8 ) & 0xFF ) + amount ;
259+ b = (rgb & 0xFF ) + amount ;
260+ if (r >255 ) r =255 ;
261+ if (g >255 ) g =255 ;
262+ if (b >255 ) b =255 ;
263+ p = (255 <<24 ) | (r <<16 ) | (g <<8 ) | b ;
264+ newImage .setRGB (x ,y ,p );
265+ }
266+ }
267+ return newImage ;
268+ }
269+
156270}
157271
158272
0 commit comments