Java进行时
程序人生
BlogJava
首页
新随笔
联系
聚合
管理
数据加载中……
很不错的一个生成等比例高质量缩略图的类!
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(
"
F:/200712131421190.jpg
"
,
"
F:/21851500.jpg
"
,
160
,
140
);
}
catch
(Exception e)
{
//
TODO Auto-generated catch block
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;
}
}
posted on 2007-12-13 21:57
davma
阅读(1347)
评论(3)
编辑
收藏
评论
#
re: 很不错的一个生成等比例高质量缩略图的类! 2008-01-26 13:12
臭臭熊
生成缩略图时,资源占用很大
回复
更多评论
#
re: 很不错的一个生成等比例高质量缩略图的类! 2008-05-21 19:47
ys
如何读取水印内容?
回复
更多评论
#
re: 很不错的一个生成等比例高质量缩略图的类![未登录]
2010-09-06 15:18
ddd
@ys
laji
回复
更多评论
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
Chat2DB
C++博客
博问
管理
<
2008年5月
>
日
一
二
三
四
五
六
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
统计
随笔 - 1
文章 - 2
评论 - 9
引用 - 0
常用链接
我的随笔
我的评论
我的参与
最新评论
留言簿
(2)
给我留言
查看公开留言
查看私人留言
随笔档案
2007年12月 (1)
2007年11月 (1)
文章分类
Java图像操作
(rss)
数据库(1)
(rss)
文章档案
2008年12月 (1)
搜索
最新评论
1. re: Java添加水印(图片水印,文字水印)[未登录]
thank you
--李
2. re: 很不错的一个生成等比例高质量缩略图的类![未登录]
@ys
laji
--ddd
3. re: Java添加水印(图片水印,文字水印)
跟.net差不多!
--t
4. re: Java添加水印(图片水印,文字水印)
值得学习
--hemingwang0902
5. re: 很不错的一个生成等比例高质量缩略图的类!
如何读取水印内容?
--ys