俊星的BLOG

JAVA图像缩放处理

今天在网上看到了一篇关于JAVA图像处理的文章,博主贴出了一个处理类:特点是高品质缩小,具体代码如下:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

public class ImageScale {

    
private int width;
    
private int height;
    
private int scaleWidth;
    
double support = (double3.0;
    
double[] contrib;
    
double[] normContrib;
    
double[] tmpContrib;
    
int startContrib, stopContrib;
    
int nDots;
    
int nHalfDots;

    
public BufferedImage imageZoomOut(BufferedImage srcBufferImage, int w, int h, boolean lockScale) {
        width 
= srcBufferImage.getWidth();
        height 
= srcBufferImage.getHeight();
        scaleWidth 
= w;
        
if (lockScale) {
            h 
= w * height / width;
        }


        
if (DetermineResultSize(w, h) == 1{
            
return srcBufferImage;
        }

        CalContrib();
        BufferedImage pbOut 
= HorizontalFiltering(srcBufferImage, w);
        BufferedImage pbFinalOut 
= VerticalFiltering(pbOut, h);
        
return pbFinalOut;
    }


    
/**
     * 决定图像尺寸
     
*/

    
private int DetermineResultSize(int w, int h) {
        
double scaleH, scaleV;
        scaleH 
= (double) w / (double) width;
        scaleV 
= (double) h / (double) height;
        
// 需要判断一下scaleH,scaleV,不做放大操作
        if (scaleH >= 1.0 && scaleV >= 1.0{
            
return 1;
        }

        
return 0;

    }
 // end of DetermineResultSize()

    
private double Lanczos(int i, int inWidth, int outWidth, double Support) {
        
double x;

        x 
= (double) i * (double) outWidth / (double) inWidth;

        
return Math.sin(x * Math.PI) / (x * Math.PI) * Math.sin(x * Math.PI / Support) / (x * Math.PI / Support);

    }
 // end of Lanczos()

    
//
    
// Assumption: same horizontal and vertical scaling factor
    
//
    private void CalContrib() {
        nHalfDots 
= (int) ((double) width * support / (double) scaleWidth);
        nDots 
= nHalfDots * 2 + 1;
        
try {
            contrib 
= new double[nDots];
            normContrib 
= new double[nDots];
            tmpContrib 
= new double[nDots];
        }
 catch (Exception e) {
            System.out.println(
"init contrib,normContrib,tmpContrib" + e);
        }


        
int center = nHalfDots;
        contrib[center] 
= 1.0;

        
double weight = 0.0;
        
int i = 0;
        
for (i = 1; i <= center; i++{
            contrib[center 
+ i] = Lanczos(i, width, scaleWidth, support);
            weight 
+= contrib[center + i];
        }


        
for (i = center - 1; i >= 0; i--{
            contrib[i] 
= contrib[center * 2 - i];
        }


        weight 
= weight * 2 + 1.0;

        
for (i = 0; i <= center; i++{
            normContrib[i] 
= contrib[i] / weight;
        }


        
for (i = center + 1; i < nDots; i++{
            normContrib[i] 
= normContrib[center * 2 - i];
        }

    }
 // end of CalContrib()

    
// 处理边缘
    private void CalTempContrib(int start, int stop) {
        
double weight = 0;

        
int i = 0;
        
for (i = start; i <= stop; i++{
            weight 
+= contrib[i];
        }


        
for (i = start; i <= stop; i++{
            tmpContrib[i] 
= contrib[i] / weight;
        }


    }
 // end of CalTempContrib()

    
private int GetRedValue(int rgbValue) {
        
int temp = rgbValue & 0x00ff0000;
        
return temp >> 16;
    }


    
private int GetGreenValue(int rgbValue) {
        
int temp = rgbValue & 0x0000ff00;
        
return temp >> 8;
    }


    
private int GetBlueValue(int rgbValue) {
        
return rgbValue & 0x000000ff;
    }


    
private int ComRGB(int redValue, int greenValue, int blueValue) {

        
return (redValue << 16+ (greenValue << 8+ blueValue;
    }


    
// 行水平滤波
    private int HorizontalFilter(BufferedImage bufImg, int startX, int stopX, int start, int stop, int y,
            
double[] pContrib) {
        
double valueRed = 0.0;
        
double valueGreen = 0.0;
        
double valueBlue = 0.0;
        
int valueRGB = 0;
        
int i, j;

        
for (i = startX, j = start; i <= stopX; i++, j++{
            valueRGB 
= bufImg.getRGB(i, y);

            valueRed 
+= GetRedValue(valueRGB) * pContrib[j];
            valueGreen 
+= GetGreenValue(valueRGB) * pContrib[j];
            valueBlue 
+= GetBlueValue(valueRGB) * pContrib[j];
        }


        valueRGB 
= ComRGB(Clip((int) valueRed), Clip((int) valueGreen), Clip((int) valueBlue));
        
return valueRGB;

    }
 // end of HorizontalFilter()

    
// 图片水平滤波
    private BufferedImage HorizontalFiltering(BufferedImage bufImage, int iOutW) {
        
int dwInW = bufImage.getWidth();
        
int dwInH = bufImage.getHeight();
        
int value = 0;
        BufferedImage pbOut 
= new BufferedImage(iOutW, dwInH, BufferedImage.TYPE_INT_RGB);

        
for (int x = 0; x < iOutW; x++{

            
int startX;
            
int start;
            
int X = (int) (((double) x) * ((double) dwInW) / ((double) iOutW) + 0.5);
            
int y = 0;

            startX 
= X - nHalfDots;
            
if (startX < 0{
                startX 
= 0;
                start 
= nHalfDots - X;
            }
 else {
                start 
= 0;
            }


            
int stop;
            
int stopX = X + nHalfDots;
            
if (stopX > (dwInW - 1)) {
                stopX 
= dwInW - 1;
                stop 
= nHalfDots + (dwInW - 1 - X);
            }
 else {
                stop 
= nHalfDots * 2;
            }


            
if (start > 0 || stop < nDots - 1{
                CalTempContrib(start, stop);
                
for (y = 0; y < dwInH; y++{
                    value 
= HorizontalFilter(bufImage, startX, stopX, start, stop, y, tmpContrib);
                    pbOut.setRGB(x, y, value);
                }

            }
 else {
                
for (y = 0; y < dwInH; y++{
                    value 
= HorizontalFilter(bufImage, startX, stopX, start, stop, y, normContrib);
                    pbOut.setRGB(x, y, value);
                }

            }

        }


        
return pbOut;

    }
 // end of HorizontalFiltering()

    
private int VerticalFilter(BufferedImage pbInImage, int startY, int stopY, int start, int stop, int x,
            
double[] pContrib) {
        
double valueRed = 0.0;
        
double valueGreen = 0.0;
        
double valueBlue = 0.0;
        
int valueRGB = 0;
        
int i, j;

        
for (i = startY, j = start; i <= stopY; i++, j++{
            valueRGB 
= pbInImage.getRGB(x, i);

            valueRed 
+= GetRedValue(valueRGB) * pContrib[j];
            valueGreen 
+= GetGreenValue(valueRGB) * pContrib[j];
            valueBlue 
+= GetBlueValue(valueRGB) * pContrib[j];
        }


        valueRGB 
= ComRGB(Clip((int) valueRed), Clip((int) valueGreen), Clip((int) valueBlue));
        
// System.out.println(valueRGB);
        return valueRGB;

    }
 // end of VerticalFilter()

    
private BufferedImage VerticalFiltering(BufferedImage pbImage, int iOutH) {
        
int iW = pbImage.getWidth();
        
int iH = pbImage.getHeight();
        
int value = 0;
        BufferedImage pbOut 
= new BufferedImage(iW, iOutH, BufferedImage.TYPE_INT_RGB);

        
for (int y = 0; y < iOutH; y++{

            
int startY;
            
int start;
            
int Y = (int) (((double) y) * ((double) iH) / ((double) iOutH) + 0.5);

            startY 
= Y - nHalfDots;
            
if (startY < 0{
                startY 
= 0;
                start 
= nHalfDots - Y;
            }
 else {
                start 
= 0;
            }


            
int stop;
            
int stopY = Y + nHalfDots;
            
if (stopY > (int) (iH - 1)) {
                stopY 
= iH - 1;
                stop 
= nHalfDots + (iH - 1 - Y);
            }
 else {
                stop 
= nHalfDots * 2;
            }


            
if (start > 0 || stop < nDots - 1{
                CalTempContrib(start, stop);
                
for (int x = 0; x < iW; x++{
                    value 
= VerticalFilter(pbImage, startY, stopY, start, stop, x, tmpContrib);
                    pbOut.setRGB(x, y, value);
                }

            }
 else {
                
for (int x = 0; x < iW; x++{
                    value 
= VerticalFilter(pbImage, startY, stopY, start, stop, x, normContrib);
                    pbOut.setRGB(x, y, value);
                }

            }


        }


        
return pbOut;

    }
 // end of VerticalFiltering()

    
int Clip(int x) {
        
if (x < 0)
            
return 0;
        
if (x > 255)
            
return 255;
        
return x;
    }


    
public static void main(String[] args) throws IOException {
        ImageScale is 
= new ImageScale();
        String path 
= "D:\\My Documents\\My Pictures\\pictrue\\";
        BufferedImage image1 
= ImageIO.read(new File(path + "test.jpg"));
        
int w = 200, h = 400;
        BufferedImage image2 
= is.imageZoomOut(image1, w, h, true);
        FileOutputStream out 
= new FileOutputStream(path + "test_2.jpg");
        ImageIO.write(image2, 
"jpeg", out);
    }

}

上面的代码中,本人做了一点小改进:imageZoomOut方法中,添加了一个lockScale参数,如果为true则表明保持纵横比。
程序运行的效果如下:
test.jpg(原图):


test_2.jpg(程序生成的图片):


posted on 2009-05-23 13:37 俊星 阅读(4175) 评论(1)  编辑  收藏

评论

# re: JAVA图像缩放处理[未登录] 2014-11-24 15:13 test

不错的方法  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: