JAVA實現圖像縮放(通過 java.awt.geom的仿射變換結合java.awt.image的各種插值方法實現)。
程序分為2部分:
- 實現標准封裝ImageScale功能
- 代碼塊去測試和使用ImageScale類的效果,以及對其中RGB元素通過移位手段的提取
- package com.han;
-
- import java.awt.geom.AffineTransform;
- import java.awt.image.AffineTransformOp;
- import java.awt.image.BufferedImage;
-
- public class ImageScale {
-
- /**
- * It is designed for scaling images. Developed by Gaowen HAN.
- * @param in the source image
- * @param sx the width scale ratio
- * @param sy the height scale ratio
- * @param interpolationType "1" represents <code>AffineTransformOp.TYPE_NEAREST_NEIGHBOR</code>;
- * "2" represents <code>AffineTransformOp.TYPE_BILINEAR</code>;
- * "3" represents <code>AffineTransformOp.TYPE_BICUBIC</code>;
- * @return the scaled image
- */
- public static BufferedImage scale(BufferedImage in,
- double sx,
- double sy,
- int interpolationType){
- AffineTransform matrix=new AffineTransform(); //仿射變換
- matrix.scale(sx,sy);
- AffineTransformOp op = null;
- if (interpolationType==1){
- op=new AffineTransformOp(matrix, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
- }else if (interpolationType==2){
- op=new AffineTransformOp(matrix, AffineTransformOp.TYPE_BILINEAR);
- }else if (interpolationType==3){
- op=new AffineTransformOp(matrix, AffineTransformOp.TYPE_BICUBIC);
- }else{
- try {
- throw new Exception("input interpolation type from 1-3 !");
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- int width = (int)((double)in.getWidth() * sx);
- int height = (int)((double)in.getHeight() * sy);
- BufferedImage dstImage = new BufferedImage(width, height, in.getType());
- //System.out.println(in.getType());
- //BufferedImage dstImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
- //BufferedImage out=op.filter(in, dstImage);
- op.filter(in, dstImage);
- //注意下面的代碼不同, 結果背景顏色不同
- //BufferedImage out=op.filter(in, null);
- return dstImage;
- }
- }
對上面標准封裝的使用和測試,以及通過移位來提取單個像素或者圖像某一特定區域的經過包裝過的RGB值。
- package com.han;
-
- import java.awt.image.BufferedImage;
- import java.io.File;
- import java.io.IOException;
-
- import javax.imageio.ImageIO;
-
- public class Test_ImageScale {
- public static void main(String[] args){
- BufferedImage in;
- try {
- in = ImageIO.read(new File("C:/Users/HAN/Pictures/1_gaowen_han.jpg"));
- long t1 = System.currentTimeMillis(); //設定時間,以便可以比較各種不同插值的效率與系統開銷
- BufferedImage out=ImageScale.scale(in, 4, 4, 3);//進行圖像縮放
- long t2 = System.currentTimeMillis();
- //寫出結果圖片到電腦硬盤
- boolean b=ImageIO.write(out, "jpg", new File("C:/Users/HAN/Pictures/scale_gaowen_han.jpg"));
- System.out.println(b);
- System.out.println(t2-t1);
- System.out.println("Width : "+out.getWidth()+"\n"+"Height : "+out.getHeight());
-
- /* int pixel=out.getRGB(0, 0);
- int R=(pixel & 0xff0000)>>16;
- int G=(pixel & 0xff00)>>8;
- int B=(pixel & 0xff);
- System.out.println("pixel R : "+R);
- System.out.println("pixel G : "+G);
- System.out.println("pixel B : "+B);*/
- /**********對縮放後的圖像的像素RGB的提取********************/
- // 1. 直接進行單個元素的提取
- // 2. 進行圖像中一塊特定區域的像素提取
- // 3. 分別輸出,進行比較以驗證數學運算公式的正確性
- int startX=0;
- int startY=0;
- int offset=0;
- int scansize=10;
- int[] rgbArray=out.getRGB(startX, startY, 10, 10, null, offset, scansize);
- int x=8;
- int y=8;
- int pixel=out.getRGB(x, y);
- int pixel_prime = rgbArray[offset + (y-startY)*scansize + (x-startX)];
- int R,G,B;
- R=(pixel & 0xff0000)>>16;
- G=(pixel & 0xff00)>>8;
- B=(pixel & 0xff);
- /*反之,由RGB分量也可以得到包裝的顏色值
- int rbg = (255 << 24) | (r << 16) | (g << 8 )| b;*/
- System.out.println("pixel R : "+R);
- System.out.println("pixel G : "+G);
- System.out.println("pixel B : "+B);
- R=(pixel_prime & 0xff0000)>>16;
- G=(pixel_prime & 0xff00)>>8;
- B=(pixel_prime & 0xff);
- System.out.println("pixel R : "+R);
- System.out.println("pixel G : "+G);
- System.out.println("pixel B : "+B);
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- }
- }
有了像素的提取,使得能夠像Matlab,Mathematica,IDL那樣自己編寫衛星照片處理等程序。當然JAVA中有自己的很多優秀封裝庫可以直接引用,比如JAVA Advanced Image Processing等。