具体要求如下:一、切割掉原始图片的上四行和左四列像素,重新生成一张切割后图像。
二、使用原始图像的压缩算法和图像质量生成切割图片。(这才是重点)PS:压缩算法为1998年公布的标准最好是能直接运行的java代码,输入一张图片-》按要求切-》输出现在只能给100分,如果能搞定再开几个贴把剩下的200分都奉上。
二、使用原始图像的压缩算法和图像质量生成切割图片。(这才是重点)PS:压缩算法为1998年公布的标准最好是能直接运行的java代码,输入一张图片-》按要求切-》输出现在只能给100分,如果能搞定再开几个贴把剩下的200分都奉上。
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.File;import javax.imageio.ImageIO;public class CutImage {
public static void main(String[] args) {
cut("f://tu.gif","f://cut//tu1.gif",200,200,".gif");
} /**
* @param srcImage 源图片存放位置
* @param descImage 切割后图片存放位置
* @param cutWidth 切割的宽度
* @param cutHeight 切割的高度
* @param imgKind 保存的文件类型
*/
public static void cut(String srcImage, String descImage, int cutWidth,int cutHeight,String imgKind) {
try {
Image img;
ImageFilter cropFilter;
BufferedImage srcImg = ImageIO.read(new File(srcImage));
int srcWidth = srcImg.getHeight(); // 源图宽度
int srcHeight = srcImg.getWidth(); // 源图高度
if (srcWidth > cutWidth && srcHeight > cutHeight) {
Image image = srcImg.getScaledInstance(srcWidth, srcHeight,Image.SCALE_DEFAULT); int cols = 0; // 切片横向个数
int rows = 0; // 切片纵向个数
// 计算切片的横向和纵向数量
if (srcWidth % cutWidth == 0) {
cols = srcWidth / cutWidth;
} else {
cols = (int) Math.floor(srcWidth / cutWidth) + 1;
}
if (srcHeight % cutHeight == 0) {
rows = srcHeight / cutHeight;
} else {
rows = (int) Math.floor(srcHeight / cutHeight) + 1;
}
// 循环建立切片
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
cropFilter = new CropImageFilter(j * cutWidth, i * cutHeight, cutWidth, cutHeight);
img = Toolkit.getDefaultToolkit().createImage(
new FilteredImageSource(image.getSource(),cropFilter));
BufferedImage tag = new BufferedImage(cutWidth,
cutHeight, BufferedImage.TYPE_INT_RGB);
Graphics g = tag.getGraphics();
g.drawImage(img, 0, 0, null); // 绘制缩小后的图
g.dispose();
// 输出为文件
ImageIO.write(tag, "JPEG", new File(descImage
+ "_" + i + "_" + j + imgKind));
}
}
System.out.println("切割成功!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
这里先将上面,左边四个象素切掉,然后分割成若干个小图片。
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.File;import javax.imageio.ImageIO;public class CutImage {
public static void main(String[] args) {
cut("f://tu.gif","f://cut//tu1.gif",200,200,".gif");
} /**
* @param srcImage 源图片存放位置
* @param descImage 切割后图片存放位置
* @param cutWidth 切割的宽度
* @param cutHeight 切割的高度
* @param imgKind 保存的文件类型
*/
public static void cut(String srcImage, String descImage, int cutWidth,int cutHeight,String imgKind) {
try {
Image img;
Image imgafter;
ImageFilter cropFilter;
BufferedImage tag;
Graphics g;
BufferedImage srcImg = ImageIO.read(new File(srcImage));
int srcHeight = srcImg.getHeight(); // 源图宽度
int srcWidth = srcImg.getWidth(); // 源图高度
if (srcWidth > cutWidth && srcHeight > cutHeight) {
//切掉上面,左边四个像素
Image image = srcImg.getScaledInstance(srcWidth, srcHeight,Image.SCALE_DEFAULT);
cropFilter = new CropImageFilter(4, 4, srcWidth, srcHeight);
imgafter = Toolkit.getDefaultToolkit().createImage(
new FilteredImageSource(image.getSource(),cropFilter));
tag = new BufferedImage(srcWidth - 4, srcHeight - 4, BufferedImage.TYPE_INT_RGB);
g = tag.getGraphics();
g.drawImage(imgafter, 0, 0, null); // 绘制缩小后的图
g.dispose();
srcWidth -= 4;
srcHeight -= 4; //分割成多个图片
int cols = 0; // 切片横向个数
int rows = 0; // 切片纵向个数
// 计算切片的横向和纵向数量
if (srcWidth % cutWidth == 0) {
cols = srcWidth / cutWidth;
} else {
cols = (int) Math.floor(srcWidth / cutWidth) + 1;
}
if (srcHeight % cutHeight == 0) {
rows = srcHeight / cutHeight;
} else {
rows = (int) Math.floor(srcHeight / cutHeight) + 1;
}
// 循环建立切片
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
cropFilter = new CropImageFilter(j * cutWidth, i * cutHeight, cutWidth, cutHeight);
img = Toolkit.getDefaultToolkit().createImage(
new FilteredImageSource(imgafter.getSource(),cropFilter));
tag = new BufferedImage(cutWidth,
cutHeight, BufferedImage.TYPE_INT_RGB);
g = tag.getGraphics();
g.drawImage(img, 0, 0, null); // 绘制缩小后的图
g.dispose();
// 输出为文件
ImageIO.write(tag, "JPEG", new File(descImage
+ "_" + i + "_" + j + imgKind));
}
}
System.out.println("切割成功!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
然后:ImageIO.write(image, 扩展名, new File(...));
目前Java本源支持的包括:jpg、jpeg、png、gif、bmp
http://www.jhlabs.com/ip/filters/index.html最后面有很多效果图可以参考。
/**
* 获取指定文件格式
* @param obj 输入源:File, RandomAccessFile, InputStream
* @return 格式类型名,null为无法识别
* @throws IOException 异常
*/
public static String getFormatName(Object obj) throws IOException {
// Create an image input stream on the image
ImageInputStream iis = ImageIO.createImageInputStream(obj); // Find all image readers that recognize the image format
Iterator<ImageReader> iter = ImageIO.getImageReaders(iis);
if (!iter.hasNext()) {
// No readers found
return null;
} // Use the first reader
ImageReader reader = iter.next(); // Close stream
iis.close(); // Return the format name
return reader.getFormatName();
}
把所获取的格式,直接用于压缩算法名称就行了。而且 bmp 就是不压缩的。切割及保存过程很简单: public static void main(String[] args) throws Exception {
String filepath = "img.png";
// 先获取图片的压缩格式类型
InputStream is = ClassLoader.getSystemResourceAsStream(filepath);
String imageType = getFormatName(is);
System.out.println("ImageType: " + imageType);
// 切割文件后保存
InputStream source = ClassLoader.getSystemResourceAsStream(filepath);
BufferedImage imgSource = ImageIO.read(source);
BufferedImage imgAfterCut = imgSource.getSubimage(44, 55, imgSource.getWidth() - 44, imgSource.getHeight() - 55); // 直接完成切割:x, y, width, height
ImageIO.write(imgAfterCut, imageType, new File(".\\new." + imageType));
}
不能保证,各种不同软件虽然都遵循相同的压缩标准,但其所实现的压缩实际效果,是绝对不一样的。你用 rar 和 360zip ,对同一个文件进行zip压缩,结果就是完全不一样的。
所以,除非你原始图片就是使用Java的相同算法所压缩,否则重新压缩后一定不相同。此外,你可以试着用PhotoShop打开一张 jpg 图片,然后按无损压缩直接保存像素为 bmp;最后再用PhotoShop打开该bmp,然后另存为jpg;你会看到新的这张jpg和之前原始的jpg是不一样的。
所以,楼主你基本上不能执着于这个问题。
String filepath = "img.png";
// 先获取图片的压缩格式类型
InputStream is = ClassLoader.getSystemResourceAsStream(filepath);
String imageType = getFormatName(is);
System.out.println("ImageType: " + imageType);
// 切割文件后保存
InputStream source = ClassLoader.getSystemResourceAsStream(filepath);
BufferedImage imgSource = ImageIO.read(source);
BufferedImage imgAfterCut = imgSource.getSubimage(44, 55, imgSource.getWidth() - 44, imgSource.getHeight() - 55); // 直接完成切割:x, y, width, height
ImageIO.write(imgAfterCut, imageType, new File(".\\new." + imageType));
}这段代码,如果我不切的话能保证原图像和生成图像一样大小么(KB)
public class BisicImageCopy {
public static void main(String[] args) {
FileInputStream fin = null;
FileOutputStream fout = null;
try {
fin = new FileInputStream("e:\\1.jpg");
fout = new FileOutputStream("e:\\2.jpg");
byte[] b = new byte[512];
int n;
while((n = fin.read(b))!=-1){
fout.write(b,0,n-1);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
fin.close();
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
如果我用字节流拷贝的方法确实能一样大小,可是怎么能把他切掉四行四列呢,好像我改掉一位生成的图像就不能在显示了
String filepath = "e:\\1.jpg";
// 先获取图片的压缩格式类型
InputStream is = ClassLoader.getSystemResourceAsStream(filepath);
//String imageType = getFormatName(is);
//System.out.println("ImageType: " + imageType);
// 切割文件后保存
InputStream source = ClassLoader.getSystemResourceAsStream(filepath);
BufferedImage imgSource = ImageIO.read(source);
BufferedImage imgAfterCut = imgSource.getSubimage(4, 5, imgSource.getWidth() - 4, imgSource.getHeight() - 5); // 直接完成切割:x, y, width, height
ImageIO.write(imgAfterCut, "jpg", new File(".\\new." + "jpg"));
}这段代码会产生运行错误,Exception in thread "main" java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(Unknown Source)
at la.main(la.java:27)
我源文件确实是有的,
ClassLoader.getSystemResourceAsStream(filepath);
全部换成:
new FileInputStream(filepath);
我原来的写法,是假定图片在src目录中,按资源进行访问的。
JPEGCodec encoder= JPEGCodec.createJPEGEncoder(out); // 输出流
JPEGEncodeParam param= encoder.getDefaultJPEGEncodeParam(imgSource); // 原始图片参数
param.setQuality(imageQuality, false); // 设置压缩比率
encoder.setJPEGEncodeParam(param); // 设置图片参数
encoder.encode(imgSource);// 将图片进行JPEG编码并输出到out中
out.close();
另外看下Image.SCALE_DEFAULT,它也有其它属性。象素的要求达到的,颜色上,肉眼看不出的区别就可以,也不用那么精确的。
public class BisicImageCopy {
public static void main(String[] args) {
FileInputStream fin = null;
FileOutputStream fout = null;
try {
fin = new FileInputStream("e:\\1.jpg");
fout = new FileOutputStream("e:\\2.jpg");
byte[] b = new byte[512];
int n;
while((n = fin.read(b))!=-1){
fout.write(b,0,n-1);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
fin.close();
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
通过字节流拷贝方法可以完整拷贝图片,那么怎么能切掉四行四列并且让图片在显示出来呢