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
閱讀(1358)
評論(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++博客
博問
管理
Powered by:
BlogJava
Copyright © davma
<
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
主站蜘蛛池模板:
汝城县
|
尼勒克县
|
基隆市
|
高陵县
|
锡林郭勒盟
|
凤翔县
|
湘阴县
|
宁安市
|
兴宁市
|
平泉县
|
稷山县
|
崇义县
|
南阳市
|
双峰县
|
兴宁市
|
洛阳市
|
金寨县
|
修武县
|
龙南县
|
乾安县
|
广灵县
|
吉隆县
|
辉县市
|
彰化县
|
桓仁
|
天峨县
|
封丘县
|
买车
|
西平县
|
屏东县
|
新安县
|
华亭县
|
日照市
|
亚东县
|
灌云县
|
万盛区
|
都江堰市
|
古浪县
|
昌黎县
|
怀仁县
|
安徽省
|