释放一个图片裁剪的类(可指定位置、缩放比例),可以用在web中对头像进行处理

用了com.sun.media的jai-codec
完整代码了,开箱即用。
使用片段如下:
                    //crop7070
                    File fileOut = new File(uploadFolder.getAbsolutePath(), "crop_7070_" + photoFileName);
                    JpegCropper cropper7070 = new JpegCropper();
                    cropper7070.setCropScale(70f/cropInfo.getCropwidth(), 70f/cropInfo.getCropwidth());
                    boolean crop = cropper7070.crop(fileIn, fileOut, 70, 70);
                    if (!crop)
                    {
                        return false;
                    }

package xxx.xxx;

import java.awt.RenderingHints;
import java.awt.image.renderable.ParameterBlock;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.media.jai.BorderExtender;
import javax.media.jai.Interpolation;
import javax.media.jai.JAI;
import javax.media.jai.KernelJAI;
import javax.media.jai.PlanarImage;
import javax.media.jai.RenderedOp;

import com.sun.media.jai.codec.ImageEncoder;
import com.sun.media.jai.codec.JPEGEncodeParam;
import com.sun.media.jai.codec.SeekableStream;
import com.sun.media.jai.codecimpl.JPEGCodec;

public class JpegCropper
{
    private float x = 0;
    private float y = 0;
    private float scalex = 1;
    private float scaley = 1;
    private float quality = 0.8f;
    private boolean scaleAuto = false;
    
    //设置裁剪的起始坐标,如果没有调用该函数,在0,0位置开始裁剪
    public void setCropCoordinate(float x, float y)
    {
        this.x = x;
        this.y = y;
    }
    
    //设置横纵坐标下的缩放,如果没有调用该函数,不进行裁剪.其中为1表示不缩放,大于1表示拉升,小于1表示压缩
    public void setCropScale(float scalex, float scaley)
    {
        this.scalex = scalex;
        this.scaley = scaley;
    }
    
    //设置按输出和源大小等比例缩放
    public void setCropScaleAuto(boolean b)
    {
        this.scaleAuto = b;
    }
    
    //设置jpeg输出的质量
    public void setJpegOutQuality(float quality)
    {
        if (quality > 1)
        {
            return;
        }
        this.quality = quality;
    }

    //重写该函数,检查源图片的尺寸是否合适
    protected boolean sourceImgSizeCheck(float width, float height)
    {
        //默认纵横超过就不合格
        return !(width > 450 || height > 450);
    }
            
    public boolean crop(String filenameIn, String filenameOut, float targetW, float targetH)
    {
        return crop(new File(filenameIn), new File(filenameOut), targetW, targetH);
    }
    
    //裁剪目标高宽的图片
    public boolean crop(File fileIn, File fileOut, float targetW, float targetH)
    {            
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try
        {
            fis = new FileInputStream(fileIn);
            fos = new FileOutputStream(fileOut);
        }
        catch (FileNotFoundException e)
        {
            return false;
        }

        SeekableStream seekableStream = SeekableStream.wrapInputStream(fis, true);
        PlanarImage sourceImage = JAI.create("stream", seekableStream);
        if (!sourceImgSizeCheck(sourceImage.getWidth(), sourceImage.getHeight()))
        {
            //尺寸不符合要求
            return false;
        }
        
        if (this.x + targetW > sourceImage.getWidth() || this.y + targetH > sourceImage.getHeight())
        {
            //x,y,targetW或targetH参数错误
            return false;
        }
        
        if (scaleAuto)
        {
            //注意sourceImage有没有被重新赋值
            this.scalex = targetW / sourceImage.getWidth();
            this.scaley = targetH / sourceImage.getHeight();
        }

        RenderingHints copyBorderRenderingHints = new RenderingHints(JAI.KEY_BORDER_EXTENDER, BorderExtender.createInstance(BorderExtender.BORDER_COPY));
        Interpolation interpolation = Interpolation.getInstance( Interpolation.INTERP_BILINEAR); 

        ParameterBlock pbPreTranslate = new ParameterBlock();
        pbPreTranslate.addSource( sourceImage);
        pbPreTranslate.add(x); 
        pbPreTranslate.add(y); 
        pbPreTranslate.add(interpolation);
        RenderedOp translatedImage = JAI.create( "Translate", pbPreTranslate, copyBorderRenderingHints);
        sourceImage = translatedImage;
                    
        //在很多使用下,并不需要进行缩放,所以有这个检查
        if (this.scalex != 1 || this.scaley != 1)
        {
            //进行缩放
            ParameterBlock pbScale = new ParameterBlock();
            pbScale.addSource(sourceImage);
            pbScale.add(this.scalex);       //x Scale amount
            pbScale.add(this.scaley);       //y Scale amount
            pbScale.add(0.0f);              //x Translate amount
            pbScale.add(0.0f);              //y Translate amount
            pbScale.add(interpolation);                 // interpolation
            PlanarImage scaledImage = JAI.create("Scale", pbScale, copyBorderRenderingHints);
            
            sourceImage = scaledImage;
        }

        //进行裁剪
        ParameterBlock pbCropFinal = new ParameterBlock();  
        pbCropFinal.addSource( sourceImage);
        pbCropFinal.add(0.0f);  
        pbCropFinal.add(0.0f);  
        pbCropFinal.add((float)targetW);  
        pbCropFinal.add((float)targetH);
        PlanarImage croppedFinalImage = JAI.create("crop", pbCropFinal, copyBorderRenderingHints);         
        
        // Unsharpening image
        KernelJAI unsharpKernel = getLowPassKernel(3);
        ParameterBlock pbUnsharpMask = new ParameterBlock();  
        pbUnsharpMask.addSource(croppedFinalImage);
        pbUnsharpMask.add(unsharpKernel);
        pbUnsharpMask.add(0.25f);
        PlanarImage unsharpenedImage = JAI.create("UnsharpMask",pbUnsharpMask,copyBorderRenderingHints);

        // Writing image
        JPEGEncodeParam param = new JPEGEncodeParam();
        param.setQuality(this.quality);
        ImageEncoder encoder = JPEGCodec.createImageEncoder("jpeg", fos, param);
        try
        {
            encoder.encode(unsharpenedImage);
            fos.flush(); 
            fos.close();
        }
        catch (IOException e)
        {
            return false;
        }
        return true;
    }

    /** 
     * The default low-pass kernel. Every entry contains the value 1.0/(number of kernel elements)  
     */
    private static KernelJAI getLowPassKernel(int size) 
    {
        int length =  size * size;
        float [] data = new float[length];
        float value = 1.0f / (float) length;
        for (int i = 0; i< length; i++) 
        {
            data[i] = value;
        }
        return new KernelJAI(size, size, data);
    }
}

你可能感兴趣的:(Web,sun)