代码如下:
代码运行正确,但在把800*600的图象处理成640*480时,图片严重失真. (注意:是等比缩放的)
如何更改啊?
//缩略图实现,将图片(jpg,gif,bmp等等)真实的变成想要的大小
package org.yqing.yakcms.plugin.image.logic;import java.io.*;
import java.util.*;
import com.sun.image.codec.jpeg.*;
import java.awt.image.*;
import java.awt.*;
import java.net.*;
import java.applet.*;
import java.sql.*;
import javax.imageio.ImageIO;
//缩略图类,
//本java类能将jpg图片文件,进行等比或非等比的大小转换。
//具体使用方法
//s_pic(大图片路径,生成小图片路径,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度,是否等比缩放(默认为true))
public class thumbs{
String InputDir; //输入图路径
String OutputDir; //输出图路径
String InputFileName; //输入图文件名
String OutputFileName; //输出图文件名
int OutputWidth = 80; //默认输出图片宽
int OutputHeight = 80; //默认输出图片高
int rate = 0;
boolean proportion = true; //是否等比缩放标记(默认为等比缩放)
boolean deleted=false;
public thumbs() {
//初始化变量
InputDir = "";
OutputDir = "";
InputFileName = "";
OutputFileName = "";
OutputWidth = 80;
OutputHeight = 80;
rate = 0;
}
public void setInputDir(String InputDir) {
this.InputDir = InputDir;
}
public void setOutputDir(String OutputDir) {
this.OutputDir = OutputDir;
}
public void setInputFileName(String InputFileName) {
this.InputFileName = InputFileName;
}
public void setOutputFileName(String OutputFileName) {
this.OutputFileName = OutputFileName;
}
public void setOutputWidth(int OutputWidth) {
this.OutputWidth = OutputWidth;
}
public void setOutputHeight(int OutputHeight) {
this.OutputHeight = OutputHeight;
}
public void setW_H(int width, int height) {
this.OutputWidth = width;
this.OutputHeight = height;
}
public String s_pic() {
BufferedImage image;
String NewFileName;
//建立输出文件对象
File file = new File(OutputDir + OutputFileName);
FileOutputStream tempout = null;
try {
tempout = new FileOutputStream(file);
}
catch (Exception ex) {
System.out.println(ex.toString());
}
Image img = null;
Toolkit tk = Toolkit.getDefaultToolkit();
Applet app = new Applet();
MediaTracker mt = new MediaTracker(app);
try {
img = tk.getImage(InputDir + InputFileName);
mt.addImage(img, 0);
mt.waitForID(0);
}
catch (Exception e) {
e.printStackTrace();
}
if ((img.getWidth(null) ==-1)||((img.getWidth(null)<this.OutputWidth) &&(img.getHeight(null)<this.OutputHeight))) {
System.out.println(" can't read,retry!" + "<BR>");
return "no";
}
else {
int new_w;
int new_h;
if (this.proportion == true) { //判断是否是等比缩放.
//为等比缩放计算输出的图片宽度及高度
double rate1 = ( (double) img.getWidth(null)) / (double) OutputWidth +
0.1;
double rate2 = ( (double) img.getHeight(null)) / (double) OutputHeight +
0.1;
double rate = rate1 > rate2 ? rate1 : rate2;
new_w = (int) ( ( (double) img.getWidth(null)) / rate);
new_h = (int) ( ( (double) img.getHeight(null)) / rate);
}
else {
new_w = OutputWidth; //输出的图片宽度
new_h = OutputHeight; //输出的图片高度
}
BufferedImage buffImg = new BufferedImage(new_w, new_h,
BufferedImage.TYPE_INT_RGB);
Graphics g = buffImg.createGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, new_w, new_h);
g.drawImage(img, 0, 0, new_w, new_h, null);
g.dispose();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(tempout);
try {
encoder.encode(buffImg);
tempout.close();
}
catch (IOException ex) {
System.out.println(ex.toString());
}
}
if(deleted)
{
File file1 = new File(OutputDir +OutputFileName);//删除原来的,并将文件重命名 File file2 = new File(InputDir + InputFileName);
if(file2.exists() && file2.isFile())
{ file2.delete(); }
file1.renameTo(file2);
} return "ok";
}
public String s_pic(String InputDir, String OutputDir, String InputFileName,
String OutputFileName) {
//输入图路径
this.InputDir = InputDir;
//输出图路径
this.OutputDir = OutputDir;
//输入图文件名
this.InputFileName = InputFileName;
//输出图文件名
this.OutputFileName = OutputFileName;
return s_pic();
}
public String s_pic(String InputDir, String OutputDir, String InputFileName,
String OutputFileName, int
width, int height, boolean gp,boolean isDeleted) {
//输入图路径
this.InputDir = InputDir;
//输出图路径
this.OutputDir = OutputDir;
//输入图文件名
this.InputFileName = InputFileName;
//输出图文件名
this.OutputFileName = OutputFileName;
//设置图片长宽
setW_H(width, height);
//是否是等比缩放 标记
this.proportion = gp;
this.deleted=isDeleted;
return s_pic();
}
}
代码运行正确,但在把800*600的图象处理成640*480时,图片严重失真. (注意:是等比缩放的)
如何更改啊?
//缩略图实现,将图片(jpg,gif,bmp等等)真实的变成想要的大小
package org.yqing.yakcms.plugin.image.logic;import java.io.*;
import java.util.*;
import com.sun.image.codec.jpeg.*;
import java.awt.image.*;
import java.awt.*;
import java.net.*;
import java.applet.*;
import java.sql.*;
import javax.imageio.ImageIO;
//缩略图类,
//本java类能将jpg图片文件,进行等比或非等比的大小转换。
//具体使用方法
//s_pic(大图片路径,生成小图片路径,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度,是否等比缩放(默认为true))
public class thumbs{
String InputDir; //输入图路径
String OutputDir; //输出图路径
String InputFileName; //输入图文件名
String OutputFileName; //输出图文件名
int OutputWidth = 80; //默认输出图片宽
int OutputHeight = 80; //默认输出图片高
int rate = 0;
boolean proportion = true; //是否等比缩放标记(默认为等比缩放)
boolean deleted=false;
public thumbs() {
//初始化变量
InputDir = "";
OutputDir = "";
InputFileName = "";
OutputFileName = "";
OutputWidth = 80;
OutputHeight = 80;
rate = 0;
}
public void setInputDir(String InputDir) {
this.InputDir = InputDir;
}
public void setOutputDir(String OutputDir) {
this.OutputDir = OutputDir;
}
public void setInputFileName(String InputFileName) {
this.InputFileName = InputFileName;
}
public void setOutputFileName(String OutputFileName) {
this.OutputFileName = OutputFileName;
}
public void setOutputWidth(int OutputWidth) {
this.OutputWidth = OutputWidth;
}
public void setOutputHeight(int OutputHeight) {
this.OutputHeight = OutputHeight;
}
public void setW_H(int width, int height) {
this.OutputWidth = width;
this.OutputHeight = height;
}
public String s_pic() {
BufferedImage image;
String NewFileName;
//建立输出文件对象
File file = new File(OutputDir + OutputFileName);
FileOutputStream tempout = null;
try {
tempout = new FileOutputStream(file);
}
catch (Exception ex) {
System.out.println(ex.toString());
}
Image img = null;
Toolkit tk = Toolkit.getDefaultToolkit();
Applet app = new Applet();
MediaTracker mt = new MediaTracker(app);
try {
img = tk.getImage(InputDir + InputFileName);
mt.addImage(img, 0);
mt.waitForID(0);
}
catch (Exception e) {
e.printStackTrace();
}
if ((img.getWidth(null) ==-1)||((img.getWidth(null)<this.OutputWidth) &&(img.getHeight(null)<this.OutputHeight))) {
System.out.println(" can't read,retry!" + "<BR>");
return "no";
}
else {
int new_w;
int new_h;
if (this.proportion == true) { //判断是否是等比缩放.
//为等比缩放计算输出的图片宽度及高度
double rate1 = ( (double) img.getWidth(null)) / (double) OutputWidth +
0.1;
double rate2 = ( (double) img.getHeight(null)) / (double) OutputHeight +
0.1;
double rate = rate1 > rate2 ? rate1 : rate2;
new_w = (int) ( ( (double) img.getWidth(null)) / rate);
new_h = (int) ( ( (double) img.getHeight(null)) / rate);
}
else {
new_w = OutputWidth; //输出的图片宽度
new_h = OutputHeight; //输出的图片高度
}
BufferedImage buffImg = new BufferedImage(new_w, new_h,
BufferedImage.TYPE_INT_RGB);
Graphics g = buffImg.createGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, new_w, new_h);
g.drawImage(img, 0, 0, new_w, new_h, null);
g.dispose();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(tempout);
try {
encoder.encode(buffImg);
tempout.close();
}
catch (IOException ex) {
System.out.println(ex.toString());
}
}
if(deleted)
{
File file1 = new File(OutputDir +OutputFileName);//删除原来的,并将文件重命名 File file2 = new File(InputDir + InputFileName);
if(file2.exists() && file2.isFile())
{ file2.delete(); }
file1.renameTo(file2);
} return "ok";
}
public String s_pic(String InputDir, String OutputDir, String InputFileName,
String OutputFileName) {
//输入图路径
this.InputDir = InputDir;
//输出图路径
this.OutputDir = OutputDir;
//输入图文件名
this.InputFileName = InputFileName;
//输出图文件名
this.OutputFileName = OutputFileName;
return s_pic();
}
public String s_pic(String InputDir, String OutputDir, String InputFileName,
String OutputFileName, int
width, int height, boolean gp,boolean isDeleted) {
//输入图路径
this.InputDir = InputDir;
//输出图路径
this.OutputDir = OutputDir;
//输入图文件名
this.InputFileName = InputFileName;
//输出图文件名
this.OutputFileName = OutputFileName;
//设置图片长宽
setW_H(width, height);
//是否是等比缩放 标记
this.proportion = gp;
this.deleted=isDeleted;
return s_pic();
}
}
[code=Java]
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;//生成等比例高质量缩略图
public class ScaleImage{ private int width;
private int height;
private int scaleWidth;
double support=(double)3.0;
double PI=(double)3.14159265358978;
double[] contrib;
double[] normContrib;
double[] tmpContrib;
int startContrib, stopContrib;
int nDots;
int nHalfDots; /**
* Start: Use Lanczos filter to replace the original algorithm for image
* scaling. Lanczos improves quality of the scaled image modify by :blade
*/
public static void main(String[] args){
ScaleImage is=new ScaleImage();
try{
is.saveImageAsJpg("d:/008.jpg","d:/008bre.jpg",1024,768);
}catch(Exception e){
e.printStackTrace();
}
} // fromFileStr原图片地址,saveToFileStr生成缩略图地址,formatWideth生成图片宽度,formatHeight高度
public void saveImageAsJpg(String fromFileStr,String saveToFileStr,
int formatWideth,int formatHeight) throws Exception{
BufferedImage srcImage;
File saveFile=new File(saveToFileStr);
File fromFile=new File(fromFileStr);
srcImage=javax.imageio.ImageIO.read(fromFile); // construct image
int imageWideth=srcImage.getWidth(null);
int imageHeight=srcImage.getHeight(null);
int changeToWideth=0;
int changeToHeight=0;
if(imageWideth>0&&imageHeight>0){
// flag=true;
if(imageWideth/imageHeight>=formatWideth/formatHeight){
if(imageWideth>formatWideth){
changeToWideth=formatWideth;
changeToHeight=(imageHeight*formatWideth)/imageWideth;
}else{
changeToWideth=imageWideth;
changeToHeight=imageHeight;
}
}else{
if(imageHeight>formatHeight){
changeToHeight=formatHeight;
changeToWideth=(imageWideth*formatHeight)/imageHeight;
}else{
changeToWideth=imageWideth;
changeToHeight=imageHeight;
}
}
} srcImage=imageZoomOut(srcImage,changeToWideth,changeToHeight);
ImageIO.write(srcImage,"JPEG",saveFile);
} public BufferedImage imageZoomOut(BufferedImage srcBufferImage,int w,int h){
width=srcBufferImage.getWidth();
height=srcBufferImage.getHeight();
scaleWidth=w; 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*PI)/(x*PI)*Math.sin(x*PI/Support)/(x*PI/Support); } 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];
// System.out.println(valueRed+"->"+Clip((int)valueRed)+"<-");
//
// System.out.println(valueGreen+"->"+Clip((int)valueGreen)+"<-");
// System.out.println(valueBlue+"->"+Clip((int)valueBlue)+"<-"+"-->");
} 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;
}}[/code]
换换试试,用SUN的那个包,没试过,不提供意见