如何在Java中进行图片剪裁 疯狂JAVA

Python014

如何在Java中进行图片剪裁 疯狂JAVA,第1张

package test

import java.awt.Color

import java.awt.Graphics2D

import java.awt.Image

import java.awt.geom.AffineTransform

import java.awt.image.AffineTransformOp

import java.awt.image.BufferedImage

import java.io.File

import java.io.IOException

import java.nio.Buffer

import javax.imageio.ImageIO

import javax.imageio.stream.ImageOutputStream

/**

 * 裁剪、缩放图片工具类

 * 

 * @author CSDN 没有梦想-何必远方

 */

public class ImgUtils {

/**

 * 缩放图片方法

 * 

 * @param srcImageFile

 *            要缩放的图片路径

 * @param result

 *            缩放后的图片路径

 * @param height

 *            目标高度像素

 * @param width

 *            目标宽度像素

 * @param bb

 *            是否补白

 */

public final static void scale(String srcImageFile, String result,

int height, int width, boolean bb) {

try {

double ratio = 0.0 // 缩放比例

File f = new File(srcImageFile)

BufferedImage bi = ImageIO.read(f)

Image itemp = bi.getScaledInstance(width, height, bi.SCALE_SMOOTH)// bi.SCALE_SMOOTH

// 选择图像平滑度比缩放速度具有更高优先级的图像缩放算法。

// 计算比例

if ((bi.getHeight() > height) || (bi.getWidth() > width)) {

double ratioHeight = (new Integer(height)).doubleValue()

/ bi.getHeight()

double ratioWhidth = (new Integer(width)).doubleValue()

/ bi.getWidth()

if (ratioHeight > ratioWhidth) {

ratio = ratioHeight

} else {

ratio = ratioWhidth

}

AffineTransformOp op = new AffineTransformOp(AffineTransform// 仿射转换

.getScaleInstance(ratio, ratio), null)// 返回表示剪切变换的变换

itemp = op.filter(bi, null)// 转换源 BufferedImage 并将结果存储在目标

// BufferedImage 中。

}

if (bb) {// 补白

BufferedImage image = new BufferedImage(width, height,

BufferedImage.TYPE_INT_RGB)// 构造一个类型为预定义图像类型之一的

// BufferedImage。

Graphics2D g = image.createGraphics()// 创建一个

// Graphics2D,可以将它绘制到此

// BufferedImage 中。

g.setColor(Color.white)// 控制颜色

g.fillRect(0, 0, width, height)// 使用 Graphics2D 上下文的设置,填充 Shape

// 的内部区域。

if (width == itemp.getWidth(null))

g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2,

itemp.getWidth(null), itemp.getHeight(null),

Color.white, null)

else

g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0,

itemp.getWidth(null), itemp.getHeight(null),

Color.white, null)

g.dispose()

itemp = image

}

ImageIO.write((BufferedImage) itemp, "JPEG", new File(result)) // 输出压缩图片

} catch (IOException e) {

e.printStackTrace()

}

}

/**

 * 裁剪图片方法

 * 

 * @param bufferedImage

 *            图像源

 * @param startX

 *            裁剪开始x坐标

 * @param startY

 *            裁剪开始y坐标

 * @param endX

 *            裁剪结束x坐标

 * @param endY

 *            裁剪结束y坐标

 * @return

 */

public static BufferedImage cropImage(BufferedImage bufferedImage,

int startX, int startY, int endX, int endY) {

int width = bufferedImage.getWidth()

int height = bufferedImage.getHeight()

if (startX == -1) {

startX = 0

}

if (startY == -1) {

startY = 0

}

if (endX == -1) {

endX = width - 1

}

if (endY == -1) {

endY = height - 1

}

BufferedImage result = new BufferedImage(endX - startX, endY - startY,

4)

for (int x = startX x < endX ++x) {

for (int y = startY y < endY ++y) {

int rgb = bufferedImage.getRGB(x, y)

result.setRGB(x - startX, y - startY, rgb)

}

}

return result

}

public static void main(String[] args) throws IOException {

File input = new File("input.jpg")

BufferedImage img = ImageIO.read(input)

cropImage(img, 10, 10, 20, 20)

File output = new File("output.jpg")

ImageIO.write(img, "jpg", output)

}

}

getSubimage方法是进行图片裁剪。

举例:

public static void main(String[] args) {

try {

//从特定文件载入

BufferedImage bi = ImageIO.read(new File("c:\\test.png"))

bi.getSubimage(0, 0, 10, 10)//前两个值是坐标位置X、Y,后两个是长和宽

} catch (IOException e) {

e.printStackTrace()

}

}

以下是进行的图片压缩,涉及到多个工具类。

/**

* 图片工具类

* 压缩图片大小

* @author Cyw

* @version 1.0

*/

public class ZIPImage {

private File file = null

private String outPutFilePath

private String inPutFilePath

private String inPutFileName

private boolean autoBuildFileName

private String outPutFileName

private int outPutFileWidth = 100// 默认输出图片宽

private int outPutFileHeight = 100// 默认输出图片高

private static boolean isScaleZoom = true// 是否按比例缩放

public ZIPImage() {

outPutFilePath = ""

inPutFilePath = ""

inPutFileName = ""

autoBuildFileName = true

outPutFileName = ""

}

/**

* @param ipfp

* 源文件夹路径

* @param ipfn

* 源文件名

* @param opfp

* 目标文件路径

* @param opfn

* 目标文件名

*/

public ZIPImage(String ipfp, String ipfn, String opfp, String opfn) {

outPutFilePath = opfp

inPutFilePath = ipfp

inPutFileName = ipfn

autoBuildFileName = true

outPutFileName = opfn

}

/**

* @param ipfp

* 源文件夹路径

* @param ipfn

* 源文件名

* @param opfp

* 目标文件路径

* @param opfn

* 目标文件名

* @param aBFN

* 是否自动生成目标文件名

*/

public ZIPImage(String ipfp, String ipfn, String opfp, String opfn,

boolean aBFN) {

outPutFilePath = opfp

inPutFilePath = ipfp

inPutFileName = ipfn

autoBuildFileName = aBFN

outPutFileName = opfn

}

public boolean isAutoBuildFileName() {

return autoBuildFileName

}

public void setAutoBuildFileName(boolean autoBuildFileName) {

this.autoBuildFileName = autoBuildFileName

}

public String getInPutFilePath() {

return inPutFilePath

}

public void setInPutFilePath(String inPutFilePath) {

this.inPutFilePath = inPutFilePath

}

public String getOutPutFileName() {

return outPutFileName

}

public void setOutPutFileName(String outPutFileName) {

this.outPutFileName = outPutFileName

}

public String getOutPutFilePath() {

return outPutFilePath

}

public void setOutPutFilePath(String outPutFilePath) {

this.outPutFilePath = outPutFilePath

}

public int getOutPutFileHeight() {

return outPutFileHeight

}

public void setOutPutFileHeight(int outPutFileHeight) {

this.outPutFileHeight = outPutFileHeight

}

public int getOutPutFileWidth() {

return outPutFileWidth

}

public void setOutPutFileWidth(int outPutFileWidth) {

this.outPutFileWidth = outPutFileWidth

}

public boolean isScaleZoom() {

return isScaleZoom

}

public void setScaleZoom(boolean isScaleZoom) {

this.isScaleZoom = isScaleZoom

}

public String getInPutFileName() {

return inPutFileName

}

public void setInPutFileName(String inPutFileName) {

this.inPutFileName = inPutFileName

}

/**

* 压缩图片大小

* @return boolean

*/

public boolean compressImage() {

boolean flag = false

try {

if (inPutFilePath.trim().equals("")) {

throw new NullPointerException("源文件夹路径不存在。")

}

if (inPutFileName.trim().equals("")) {

throw new NullPointerException("图片文件路径不存在。")

}

if (outPutFilePath.trim().equals("")) {

throw new NullPointerException("目标文件夹路径地址为空。")

} else {

if (!ZIPImage.mddir(outPutFilePath)) {

throw new FileNotFoundException(outPutFilePath

+ " 文件夹创建失败!")

}

}

if (this.autoBuildFileName) { // 自动生成文件名

String tempFile[] = getFileNameAndExtName(inPutFileName)

outPutFileName = tempFile[0] + "_cyw." + tempFile[1]

compressPic()

} else {

if (outPutFileName.trim().equals("")) {

throw new NullPointerException("目标文件名为空。")

}

compressPic()

}

} catch (Exception e) {

flag = false

e.printStackTrace()

return flag

}

return flag

}

// 图片处理

private void compressPic() throws Exception {

try {

// 获得源文件

file = new File(inPutFilePath + inPutFileName)

if (!file.exists()) {

throw new FileNotFoundException(inPutFilePath + inPutFileName

+ " 文件不存在!")

}

Image img = ImageIO.read(file)

// 判断图片格式是否正确

if (img.getWidth(null) == -1) {

throw new Exception("文件不可读!")

} else {

int newWidth

int newHeight

// 判断是否是等比缩放

if (ZIPImage.isScaleZoom == true) {

// 为等比缩放计算输出的图片宽度及高度

double rate1 = ((double) img.getWidth(null))

/ (double) outPutFileWidth + 0.1

double rate2 = ((double) img.getHeight(null))

/ (double) outPutFileHeight + 0.1

// 根据缩放比率大的进行缩放控制

double rate = rate1 >rate2 ? rate1 : rate2

newWidth = (int) (((double) img.getWidth(null)) / rate)

newHeight = (int) (((double) img.getHeight(null)) / rate)

} else {

newWidth = outPutFileWidth// 输出的图片宽度

newHeight = outPutFileHeight// 输出的图片高度

}

BufferedImage tag = new BufferedImage((int) newWidth,

(int) newHeight, BufferedImage.TYPE_INT_RGB)

/*

* Image.SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好 但速度慢

*/

tag.getGraphics().drawImage(

img.getScaledInstance(newWidth, newHeight,

Image.SCALE_SMOOTH), 0, 0, null)

FileOutputStream out = new FileOutputStream(outPutFilePath

+ outPutFileName)

JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out)

encoder.encode(tag)

out.close()

}

} catch (IOException ex) {

ex.printStackTrace()

}

}

/**

* 创建文件夹目录

* @param filePath

* @return

* @throws Exception

*/

@SuppressWarnings("unused")

private static boolean mddir(String filePath) throws Exception {

boolean flag = false

File f = new File(filePath)

if (!f.exists()) {

flag = f.mkdirs()

} else {

flag = true

}

return flag

}

/**

* 获得文件名和扩展名

* @param fullFileName

* @return

* @throws Exception

*/

private String[] getFileNameAndExtName(String fullFileName)

throws Exception {

String[] fileNames = new String[2]

if (fullFileName.indexOf(".") == -1) {

throw new Exception("源文件名不正确!")

} else {

fileNames[0] = fullFileName.substring(0, fullFileName

.lastIndexOf("."))

fileNames[1] = fullFileName

.substring(fullFileName.lastIndexOf(".") + 1)

}

return fileNames

}

public Image getSourceImage() throws IOException{

//获得源文件

file = new File(inPutFilePath + inPutFileName)

if (!file.exists()) {

throw new FileNotFoundException(inPutFilePath + inPutFileName

+ " 文件不存在!")

}

Image img = ImageIO.read(file)

return img

}

/*

* 获得图片大小 

* @path :图片路径

*/

public long getPicSize(String path) {

File file = new File(path)

return file.length()

}

}

//下面是测试程序

package com.sun.util.cyw

import java.awt.Image

import java.io.IOException

public class ImageTest {

public static void main(String[] args) throws IOException {

ZIPImage zip=new ZIPImage("d:\\","1.jpg","d:\\test\\","处理后的图片.jpg",false)

zip.setOutPutFileWidth(1000)

zip.setOutPutFileHeight(1000)

Image image=zip.getSourceImage()

long size=zip.getPicSize("d:\\1.jpg")

System.out.println("处理前的图片大小 width:"+image.getWidth(null))

System.out.println("处理前的图片大小 height:"+image.getHeight(null))

System.out.println("处理前的图片容量:"+ size +" bit")

zip.compressImage()

}

}

BufferedImage类有一个getSubimage()方法,以下来自API

public BufferedImage getSubimage(int x,

int y,

int w,

int h)

返回由指定矩形区域定义的子图像。返回的 BufferedImage 与源图像共享相同的数据数组。

参数:

x - 指定矩形区域左上角的 X 坐标

y - 指定矩形区域左上角的 Y 坐标

w - 指定矩形区域的宽度

h - 指定矩形区域的高度

返回:

BufferedImage,它是此 BufferedImage 的子图像。

抛出:

RasterFormatException - 如果指定区域不包含在此 BufferedImage 中。