版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cdnight/article/details/86710581
前言
图片处理一直是web网站的重点与难点。因为硬盘费钱,带宽更加费钱,流量一多系统分分钟崩给你看。。。
下面将解决这个问题。当然,个人写图片处理也是很费时间的,下面是参考项目与文章:
thumbnailator
Java生成缩略图之Thumbnailator
这篇文章有大部分用法,推荐:
Java使用google开源工具Thumbnailator实现图片压缩
值得注意的是,这个项目已经停滞了四年了。github上面有三页bug。。额???
所以,将它download下来直接整合到项目中,以后估计要一直改bug。。。
整合thumbnails项目
这个。。直接从官网下载项目源代码即可,整合情况如下:
比较重要的工具类
这个插件整合编写难度本来就不会很低,如果手头上没几个可靠的工具估计比较悬,这次用了一些很使用的工具类,例如用魔法数字判断一个文件类型:
package net.w2p.Shared.common.files;
public enum FileType {
//--apk 1 -- 504b03041400080808000d89f34a0000000000000000000000001400
//--apk 2 -- 504b0304140000000800000000008a6135b4bfcf360080a57c000b00
//--apk 3 -- 504b0304140000000800000000007e6cbc561fa30000c18301001400
//--apk 4 -- 504b03041400080808000052ce4a0000000000000000000000001400
//--apk 5 -- 504b0304140000000800000000007e6cbc561fa30000c18301001400
//--apk 6 -- 504b0304140000000800000000007e6cbc561fa30000c18301001400
//--apk 7 -- 504b0304140000000800000000007dec827617783d0060878d000b00
//--apk 8 -- 504b0304140000000800000000008204a0933fb23e00584790000b00
//--apk 9 -- 504b0304140000000800000000000682c35d46103e0048948f000b00
//--apk10 -- 504b030414000000080000000000b5a90c5ad3893b00ac2287000b00
/**
* JEPG.
*/
JPEG("FFD8FF",".jpg"),
//--apk暂时当成有两种。
APK1("504b030414000000080000000000",".apk"),
APK2("504b03041400080808000",".apk"),
/**
* PNG.
*/
PNG("89504E47",".png"),
/**
* GIF.
*/
GIF("47494638",".gif"),
/**
* TIFF.
*/
TIFF("49492A00",".tiff"),
/**
* Windows Bitmap.
*/
BMP("424D",".bmp"),
/**
* CAD.
*/
DWG("41433130",".dwg"),
/**
* Adobe Photoshop.
*/
PSD("38425053",".psd"),
/**
* Rich Text Format.
*/
RTF("7B5C727466",".rtf"),
/**
* XML.
*/
XML("3C3F786D6C",".xml"),
/**
* HTML.
*/
HTML("68746D6C3E",".html"),
/**
* CSS.
*/
CSS("48544D4C207B0D0A0942",".css"),
/**
* JS.
*/
JS("696B2E71623D696B2E71",".js"),
/**
* Email [thorough only].
*/
EML("44656C69766572792D646174653A",".eml"),
/**
* Outlook Express.
*/
DBX("CFAD12FEC5FD746F",".dbx"),
/**
* Outlook (pst).
*/
PST("2142444E",".pst"),
/**
* MS Word/Excel.
*/
XLS_DOC("D0CF11E0",".doc"),
XLSX_DOCX("504B030414000600080000002100",".docx"),
/**
* ZIP Archive.
*/
ZIP("504B0304",".zip"),
/**
* Visio
*/
VSD("d0cf11e0a1b11ae10000",".xsd"),
/**
* MS Access.
*/
MDB("5374616E64617264204A",".mdb"),
/**
* WPS文字wps、表格et、演示dps都是一样的
*/
WPS("d0cf11e0a1b11ae10000",".wps"),
/**
* torrent
*/
TORRENT("6431303A637265617465",".torrent"),
/**
* WordPerfect.
*/
WPD("FF575043",".wpd"),
/**
* Postscript.
*/
EPS("252150532D41646F6265",".eps"),
/**
* Adobe Acrobat.
*/
PDF("255044462D312E",".pdf"),
/**
* Quicken.
*/
QDF("AC9EBD8F",".qdf"),
/**
* Windows Password.
*/
PWL("E3828596",".pwl"),
/**
* RAR Archive.
*/
RAR("52617221",".rar"),
/**
* JSP Archive.
*/
JSP("3C2540207061676520",".jsp"),
/**
* JAVA Archive.
*/
JAVA("7061636B61676520",".java"),
/**
* CLASS Archive.
*/
CLASS("CAFEBABE0000002E00",".class"),
/**
* JAR Archive.
*/
JAR("504B03040A000000",".jar"),
/**
* MF Archive.
*/
MF("4D616E69666573742D56",".mf"),
/**
*EXE Archive.
*/
EXE("4D5A9000030000000400",".exe"),
/**
*CHM Archive.
*/
CHM("49545346030000006000","chm"),
/*
* INI("235468697320636F6E66"), SQL("494E5345525420494E54"), BAT(
* "406563686F206f66660D"), GZ("1F8B0800000000000000"), PROPERTIES(
* "6C6F67346A2E726F6F74"), MXP(
* "04000000010000001300"),
*/
/**
* Wave.
*/
WAV("57415645",".wav"),
/**
* AVI.
*/
AVI("41564920",".avi"),
/**
* Real Audio.
*/
RAM("2E7261FD","ram"),
/**
* Real Media.
*/
RM("2E524D46",".rm"),
/**
* MPEG (mpg).
*/
MPG("000001BA",".mpg"),
/**
* Quicktime.
*/
MOV("6D6F6F76",".mov"),
/**
* Windows Media.
*/
ASF("3026B2758E66CF11",".asf"),
/**
* MIDI.
*/
MID("4D546864",".mid"),
/**
* MP4.
*/
MP4("00000020667479706d70",".mp4"),
/**
* MP3.
*/
MP3("49443303000000002176",".mp3"),
/**
* FLV.
*/
FLV("464C5601050000000900",".flv"),
UNKNOWN("","")
;
private String value = "";
/**
* Constructor.
*
* @param type
*/
private FileType(String value,String ext) {
this.value = value;
this.ext=ext;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public void setExt(String ext){
this.ext=ext;
}
public String getExt(){
return ext;
}
public String getImageType(){
if(ext==null||ext.isEmpty()){
return "";
}
return ext.trim().replace(".","");
}
private String ext;
}
package net.w2p.Shared.common.files;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
public final class FileTypeJudge {
/** * Constructor */
private FileTypeJudge() {}
/** * 将文件头转换成16进制字符串 *
* @param src 原生byte
* @return 16进制字符串 */
private static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder();
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
/**
* * 得到文件头
* @param filePath * 文件路径 *
* @return 文件头 *
* @throws IOException */
private static String getFileContent(String filePath) throws IOException {
byte[] b = new byte[28];
InputStream inputStream = null;
try {
inputStream = new FileInputStream(filePath);
inputStream.read(b, 0, 28);
} catch (IOException e) {
e.printStackTrace();
throw e;}
finally {if (inputStream != null)
{
try {inputStream.close();}
catch (IOException e)
{e.printStackTrace();throw e;}}}
return bytesToHexString(b);}
/**
* * 得到文件头
* @param fileContent * 文件内容 *
* @return 文件头 *
* @throws IOException */
private static String getFileContent(byte[] fileContent) throws IOException {
byte[] b = new byte[28];
b= Arrays.copyOfRange(fileContent,0,28);
return bytesToHexString(b);}
/**
* 判断文件类型 * *
* @param content
*文件路径 *
*@return 文件类型 */
public static FileType getType(byte[] content) throws IOException {
String fileHead = getFileContent(content);
// System.out.println("===============魔术数字:");
// System.out.println(fileHead);
if (fileHead == null || fileHead.length() == 0) {
return null;
}
fileHead = fileHead.toUpperCase();
FileType[] fileTypes = FileType.values();
for (FileType type : fileTypes) {
if (fileHead.startsWith(type.getValue().toUpperCase())) {
return type;
}}
return null;}
/**
* 判断文件类型 * *
* @param filePath *
*文件路径 *
*@return 文件类型 */
public static FileType getType(String filePath) throws IOException {
String fileHead = getFileContent(filePath);
if (fileHead == null || fileHead.length() == 0) {
return null;}fileHead = fileHead.toUpperCase();
FileType[] fileTypes = FileType.values();
for (FileType type : fileTypes) {
if (fileHead.startsWith(type.getValue())) {
return type;}}return null;}
public static void main(String args[]) throws Exception {
System.out.println(FileTypeJudge.getType("d:\\FileMonitor.java"));
}
}
添加对应的配置类以及工具类
引入依赖
WebExt下面要引入模块依赖的:
在WebExt下面添加对应的类,如下图:
这次整合的类略有点多
代码分别是:
ResizeMode
package net.w2p.WebExt.dict;
import net.w2p.Shared.common.KeyValuePair;
import java.util.ArrayList;
/***
* 图片缩放规则
* ***/
public enum ResizeMode {
KeepAspectRatio("按比例缩放",0)
,ScaleOnWith("按比例等宽缩放",1)
,ScaleOnHeight("按比例等高缩放",2)
,AbsoluteSize("绝对尺寸(严格按照尺寸缩放不惜变形)",3)
;
private String _name;
private Integer _id;
private ResizeMode(String name, Integer id) {
this._name = name;
this._id = id;
}
public String getName() {
return this._name;
}
public Integer getId() {
return this._id;
}
public static ResizeMode getTarget(Integer id) {
ResizeMode target = null;
for(ResizeMode cmd : ResizeMode.values()) {
if(cmd.getId() == id.intValue()) {
target = cmd;
break;
}
}
if(target == null) {
return null;
}
return target;
}
public static String getNameById(Integer id) {
ResizeMode target = null;
if(id==null){
return "";
}
for(ResizeMode cmd : ResizeMode.values()) {
if(cmd.getId() == id.intValue()) {
target = cmd;
break;
}
}
if(target == null) {
return "";
}
return target.getName();
}
/**
* 获得列表信息。
*/
public static ArrayList<KeyValuePair> getList() {
ArrayList<KeyValuePair> list=new ArrayList<KeyValuePair>();
for(ResizeMode cmd : ResizeMode.values()) {
KeyValuePair kv=new KeyValuePair();
kv.setKey(cmd.getId()+"");
kv.setValue(cmd.getName());
list.add(kv);
}
return list;
}
}
WaterMarkPos
package net.w2p.WebExt.dict;
import net.w2p.Shared.common.KeyValuePair;
import java.util.ArrayList;
/***
* 水印位置
* ***/
public enum WaterMarkPos {
BottomRight("右下",0)
,BottomLeft("左下",1)
,TopLeft("左上",2)
,TopRight("右上",3)
,CENTER("正中心",4)
,CenterLeft("中间左侧",5)
,CenterRight("中间右侧",6)
;
private String _name;
private Integer _id;
private WaterMarkPos(String name, Integer id) {
this._name = name;
this._id = id;
}
public String getName() {
return this._name;
}
public Integer getId() {
return this._id;
}
public static WaterMarkPos getTarget(Integer id) {
WaterMarkPos target = null;
for(WaterMarkPos cmd : WaterMarkPos.values()) {
if(cmd.getId() == id.intValue()) {
target = cmd;
break;
}
}
if(target == null) {
return null;
}
return target;
}
public static String getNameById(Integer id) {
WaterMarkPos target = null;
if(id==null){
return "";
}
for(WaterMarkPos cmd : WaterMarkPos.values()) {
if(cmd.getId() == id.intValue()) {
target = cmd;
break;
}
}
if(target == null) {
return "";
}
return target.getName();
}
/**
* 获得列表信息。
*/
public static ArrayList<KeyValuePair> getList() {
ArrayList<KeyValuePair> list=new ArrayList<KeyValuePair>();
for(WaterMarkPos cmd : WaterMarkPos.values()) {
KeyValuePair kv=new KeyValuePair();
kv.setKey(cmd.getId()+"");
kv.setValue(cmd.getName());
list.add(kv);
}
return list;
}
}
ThumbnailImage
package net.w2p.WebExt.vo;
import java.sql.Timestamp;
import java.util.Date;
public class ThumbnailImage {
public String fileMD5="";
public Integer size=0;
public byte[] fileContent=null;
public String getFileMD5() {
return fileMD5;
}
public void setFileMD5(String fileMD5) {
this.fileMD5 = fileMD5;
}
public Integer getSize() {
return size;
}
public void setSize(Integer size) {
this.size = size;
}
public byte[] getFileContent() {
return fileContent;
}
public void setFileContent(byte[] fileContent) {
this.fileContent = fileContent;
}
}
ThumbnailResult
package net.w2p.WebExt.vo;
public class ThumbnailResult {
public Boolean state=true;
public String message="";
public ThumbnailImage small=null;
public ThumbnailImage medium=null;
public ThumbnailImage large=null;
public ThumbnailImage getSmall() {
return small;
}
public void setSmall(ThumbnailImage small) {
this.small = small;
}
public ThumbnailImage getMedium() {
return medium;
}
public void setMedium(ThumbnailImage medium) {
this.medium = medium;
}
public ThumbnailImage getLarge() {
return large;
}
public void setLarge(ThumbnailImage large) {
this.large = large;
}
public Boolean getState() {
return state;
}
public void setState(Boolean state) {
this.state = state;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
GraphicImageConf
package net.w2p.WebExt.config;
import com.xxl.conf.core.annotation.XxlConf;
/****
*
* 图片处理相关设置
* 1、图片尺寸有:小small,中medium中,大large,原图四种
* 2、可设置是否打水印,设置水印位置。
* 3、图片处理是全系统通用配置,直接用注解获取即可。
* ****/
public class GraphicImageConf {
private static final String VarPrefix="graphic.image.";
/***
* 是否保存原图
* ***/
@XxlConf(VarPrefix+"enableSaveOrgPic")
public Boolean enableSaveOrgPic=false;
/***
*
* 是否允许所有观众查看原图。
* ps:只有在enableSaveOrgPic为真时,才会保存原图,这时候才有原图能开放参观。
* ***/
@XxlConf(VarPrefix+"enableVisitOrgPic")
public Boolean enableVisitOrgPic=false;
/****
* 缩放模式。
* ps:有以下模式:
* KeepAspectRatio("按比例缩放",0)
*,ScaleOnWith("按比例等宽缩放",1)
*,ScaleOnHeight("按比例等高缩放",2)
*,AbsoluteSize("绝对尺寸(严格按照尺寸缩放不惜变形)",3)
*;
* ****/
@XxlConf(VarPrefix+"resizeMode")
public Integer resizeMode=0;
/***
* 图片【small】的尺寸,字符串形式。
* ***/
@XxlConf(VarPrefix+"smallSize")
public String smallSize="320,480";
/***
* 图片【medium】的尺寸,字符串形式。
* ***/
@XxlConf(VarPrefix+"mediumSize")
public String mediumSize="400,600";
/***
* 图片【large】的尺寸,字符串形式。
* ***/
@XxlConf(VarPrefix+"largeSize")
public String largeSize="600,900";
/****
* 图片压缩质量。
* 小数。零到一之间。
* **/
@XxlConf(VarPrefix+"quality")
public Float quality=1.0f;
/***
* 是否打水印
* ****/
@XxlConf(VarPrefix+"waterMark")
public Boolean waterMark=false;
/****
*
* 水印图片的文件位置。
* 注意!水印图片可以是网址{http开头},也可以是文件的绝对路径。
* ***/
@XxlConf(VarPrefix+"waterMarkPath")
public String waterMarkPath="";
/***
* 水印位置
BottomRight("右下",0)
,BottomLeft("左下",1)
,TopLeft("左上",2)
,TopRight("右上",3)
,CENTER("正中心",4)
,CenterLeft("中间左侧",5)
,CenterRight("中间右侧",6)
* ***/
@XxlConf(VarPrefix+"waterMarkPos")
public Integer waterMarkPos=0;
/***
* 水印的透明度,0到1之间,小数。
* ***/
@XxlConf(VarPrefix+"waterMarkOpacity")
public Float waterMarkOpacity=1.0f;
public Boolean getEnableSaveOrgPic() {
return enableSaveOrgPic;
}
public void setEnableSaveOrgPic(Boolean enableSaveOrgPic) {
this.enableSaveOrgPic = enableSaveOrgPic;
}
public Boolean getEnableVisitOrgPic() {
return enableVisitOrgPic;
}
public void setEnableVisitOrgPic(Boolean enableVisitOrgPic) {
this.enableVisitOrgPic = enableVisitOrgPic;
}
public Integer getResizeMode() {
return resizeMode;
}
public void setResizeMode(Integer resizeMode) {
this.resizeMode = resizeMode;
}
public String getSmallSize() {
return smallSize;
}
public void setSmallSize(String smallSize) {
this.smallSize = smallSize;
}
public String getMediumSize() {
return mediumSize;
}
public void setMediumSize(String mediumSize) {
this.mediumSize = mediumSize;
}
public String getLargeSize() {
return largeSize;
}
public void setLargeSize(String largeSize) {
this.largeSize = largeSize;
}
public Boolean getWaterMark() {
return waterMark;
}
public void setWaterMark(Boolean waterMark) {
this.waterMark = waterMark;
}
public String getWaterMarkPath() {
return waterMarkPath;
}
public void setWaterMarkPath(String waterMarkPath) {
this.waterMarkPath = waterMarkPath;
}
public Float getWaterMarkOpacity() {
return waterMarkOpacity;
}
public void setWaterMarkOpacity(Float waterMarkOpacity) {
this.waterMarkOpacity = waterMarkOpacity;
}
public Float getQuality() {
return quality;
}
public void setQuality(Float quality) {
this.quality = quality;
}
}
GraphicImagePlugin
package net.w2p.WebExt.Plugins;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Position;
import net.coobird.thumbnailator.geometry.Positions;
import net.w2p.Shared.common.ValidateUtils;
import net.w2p.Shared.common.WebTools;
import net.w2p.Shared.common.files.FileType;
import net.w2p.Shared.common.files.FileTypeJudge;
import net.w2p.Shared.path.ClassPathHelper;
import net.w2p.Shared.path.WebRoot;
import net.w2p.WebExt.config.GraphicImageConf;
import net.w2p.WebExt.dict.ResizeMode;
import net.w2p.WebExt.dict.WaterMarkPos;
import net.w2p.WebExt.vo.ThumbnailImage;
import net.w2p.WebExt.vo.ThumbnailResult;
import org.apache.commons.io.FileUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
/***
*
* 注意,当前插件要用到CryptoPlugin,因为要算文件的md5值。
*
* ***/
public class GraphicImagePlugin {
private GraphicImageConf conf=null;
private CryptoPlugin cryptoPlugin=null;
private BufferedImage logoImg=null;
private String waterMarkLastPath="";//--将上次的水印文件路径缓存,假如不一致的话就要重新读取水印文件,缓存到内存中去。
public GraphicImagePlugin(GraphicImageConf conf,CryptoPlugin cryptoPlugin){
this.conf=conf;
this.cryptoPlugin=cryptoPlugin;
}
private class ImgSize{
public int w=0;
public int h=0;
public int getW() {
return w;
}
public void setW(int w) {
this.w = w;
}
public int getH() {
return h;
}
public void setH(int h) {
this.h = h;
}
}
private ImgSize parse2Size(String str) throws Exception{
String[] arr_size=str.split(",");
ImgSize imgSize=new ImgSize();
imgSize.h=Integer.parseInt(arr_size[1]);
imgSize.w=Integer.parseInt(arr_size[0]);
return imgSize;
}
public ThumbnailResult handle(byte[] originImageContent) throws Exception {
Boolean isLogoPathUrl=false;
URL logoUrl=null;
File logoFile=null;
if(conf.waterMark){
if(conf.waterMarkPath.trim().toLowerCase().indexOf("http")==0){
isLogoPathUrl=true;
logoUrl=new URL(conf.waterMarkPath.trim());
}
else{
isLogoPathUrl=false;
logoFile=new File(conf.waterMarkPath.trim());
}
}
if(this.conf.waterMark){
if(logoImg==null||!waterMarkLastPath.equals(conf.waterMarkPath)){
waterMarkLastPath=conf.waterMarkPath;
if(isLogoPathUrl){
logoImg=ImageIO.read(logoUrl);
}
else{
logoImg=ImageIO.read(logoFile);
}
}
}
ResizeMode resizeMode=ResizeMode.getTarget(conf.resizeMode);
WaterMarkPos pos=WaterMarkPos.getTarget(conf.waterMarkPos);
ArrayList<ImgSize> sizeItems=new ArrayList<>();
sizeItems.add(parse2Size(conf.smallSize));
sizeItems.add(parse2Size(conf.mediumSize));
sizeItems.add(parse2Size(conf.largeSize));
ArrayList<ThumbnailImage> imgList=new ArrayList<>();
ThumbnailImage tmpImgInfo=null;
Thumbnails.Builder<BufferedImage> tmpBuilder=null;
BufferedImage orgImg=null;
ByteArrayOutputStream bout = null;
{
ByteArrayInputStream in = new ByteArrayInputStream(originImageContent); //将b作为输入流;
orgImg = ImageIO.read(in);
in.close();
}
for(ImgSize sizeItem:sizeItems){
tmpImgInfo=new ThumbnailImage();
tmpBuilder = Thumbnails.of(orgImg);
switch (resizeMode){
case KeepAspectRatio:
tmpBuilder.size(sizeItem.w,sizeItem.h);
break;
case ScaleOnWith:
tmpBuilder.width(sizeItem.w);
break;
case ScaleOnHeight:
tmpBuilder.height(sizeItem.h);
break;
case AbsoluteSize:
tmpBuilder.size(sizeItem.w,sizeItem.h).keepAspectRatio(false);
default:
throw new Exception("缩放模式异常,无法确认缩放模式!");
}
if(conf.waterMark){
//--打水印
switch(pos){
case BottomRight:tmpBuilder.watermark(Positions.BOTTOM_RIGHT,logoImg,conf.waterMarkOpacity);break;
case BottomLeft:tmpBuilder.watermark(Positions.BOTTOM_LEFT,logoImg,conf.waterMarkOpacity);break;
case TopLeft:tmpBuilder.watermark(Positions.TOP_LEFT,logoImg,conf.waterMarkOpacity);break;
case TopRight:tmpBuilder.watermark(Positions.TOP_RIGHT,logoImg,conf.waterMarkOpacity);break;
case CENTER:tmpBuilder.watermark(Positions.CENTER,logoImg,conf.waterMarkOpacity);break;
case CenterLeft:tmpBuilder.watermark(Positions.CENTER_LEFT,logoImg,conf.waterMarkOpacity);break;
case CenterRight:tmpBuilder.watermark(Positions.CENTER_RIGHT,logoImg,conf.waterMarkOpacity);break;
default:throw new Exception("水印位置异常,系统无法识别水印位置!代号错误!");
}
}
bout=new ByteArrayOutputStream();
tmpBuilder.outputQuality(conf.quality);
FileType fileType=FileTypeJudge.getType(originImageContent);
//--现在来判断输出格式了。
tmpBuilder.outputFormat(fileType.getImageType());
tmpBuilder.toOutputStream(bout);
byte[] resBytes=bout.toByteArray();
bout.close();
tmpImgInfo.fileContent=resBytes;
tmpImgInfo.size=resBytes.length;
tmpImgInfo.fileMD5=cryptoPlugin.md5(resBytes);
imgList.add(tmpImgInfo);
}
ThumbnailResult result=new ThumbnailResult();
result.small=imgList.get(0);
result.medium=imgList.get(1);
result.large=imgList.get(2);
result.setState(true);
result.setMessage("");
return result;
}
}
初始化配置中心的数据
请执行
-- 图片处理样式为全系统通用。
create or replace function "initGraphicImageConfig"(
in envName varchar
)
returns varchar
as $BODY$
declare _defaultValues varchar;
declare _envName varchar;
declare _appname varchar;
declare _prefix varchar;
declare strArrays varchar[];
declare arrItemLv1 varchar;
declare tempArrSubItem varchar;
declare valArrs varchar[];
declare item_attr varchar;
declare item_title varchar;
declare item_val varchar;
begin
if envName <> 'test' and envName<> 'ppe' and envName<> 'product' then
raise notice '环境变量异常,只能为test、ppe以及product其中一个。';
return '环境变量异常,只能为test、ppe以及product其中一个。';
end if;
_appname:='graphic';
_prefix:=concat(_appname,'.image.','');
_defaultValues:=
'enableSaveOrgPic->是否保存原图->false$$' ||
'enableVisitOrgPic->是否允许所有观众查看原图。\n\r ps:只有在enableSaveOrgPic为真时,才会保存原图,这时候才有原图能开放参观。->false$$' ||
'resizeMode->缩放模式。
* ps:有以下模式:
* KeepAspectRatio("按比例缩放",0)
*,ScaleOnWith("按比例等宽缩放",1)
*,ScaleOnHeight("按比例等高缩放",2)
*,AbsoluteSize("绝对尺寸(严格按照尺寸缩放不惜变形)",3)->0$$' ||
'smallSize->图片【small】的尺寸,字符串形式,默认为:320,480->320,480$$' ||
'mediumSize->图片【medium】的尺寸,字符串形式,默认为:400,600->400,600$$' ||
'largeSize->图片【large】的尺寸,字符串形式,默认为:600,900->600,900$$' ||
'quality->图片压缩质量。小数。零到一之间。->1.0$$' ||
'waterMark->是否打水印,默认false->false$$' ||
'waterMarkPath->水印图片的文件位置。
* 注意!水印图片可以是网址{http开头},也可以是文件的绝对路径。->$$' ||
'waterMarkOpacity->水印的透明度,0到1之间,小数。->1.0$$' ||
'waterMarkPos->水印位置
BottomRight("右下",0)
,BottomLeft("左下",1)
,TopLeft("左上",2)
,TopRight("右上",3)
,CENTER("正中心",4)
,CenterLeft("中间左侧",5)
,CenterRight("中间右侧",6)->0$$' ||
''
;
strArrays:=string_to_array(_defaultValues,'$$');
_envName:=envName;
-- fastdfs.connect_timeout_in_seconds = 5
-- fastdfs.network_timeout_in_seconds = 30
-- fastdfs.charset = UTF-8
-- fastdfs.http_anti_steal_token = false
-- fastdfs.http_secret_key = FastDFS1234567890
-- fastdfs.http_tracker_http_port = 80
-- #fastdfs.tracker_servers = tw-server:22122,10.0.11.202:22122,10.0.11.203:22122
-- fastdfs.tracker_servers = localhost:22122
-- fastdfs.visit_url = http://localhost/
-- env varchar(100) not null,
-- key varchar(200) not null,
-- appname varchar(100) not null,
-- title varchar(100) not null,
-- value varchar(2000) default NULL::character varying,
insert into xxl_conf_project (appname, title) values (_appname,'图片处理配置') on conflict ("appname") do nothing;
<<loop4BigArray>>
foreach arrItemLv1 in array strArrays
loop
if char_length(arrItemLv1) < 1 then
raise notice '空字符串无须处理';
continue ;
end if;
valArrs:=string_to_array(arrItemLv1,'->');
item_attr:=valArrs[1];
item_title:=valArrs[2];
item_val:=valArrs[3];
raise notice '属性名称:%,描述:%,当前值:%',item_attr,item_title,item_val;
raise notice '开始添加记录';
insert into xxl_conf_node("env","key","appname","title","value")
values (_envName,concat(_prefix,item_attr),_appname,item_title,item_val)
on conflict ("env","key") do nothing ;
end loop loop4BigArray;
return envName||'环境下的'||_appName||'配置成功';
end;
$BODY$ language plpgsql volatile ;
-- 记住执行下面方法分别添加三个环境下的默认数据。
-- select "initGraphicImageConfig"('test');
-- select "initGraphicImageConfig"('ppe');
-- select "initGraphicImageConfig"('product');
执行:
select "initGraphicImageConfig"('test');
select "initGraphicImageConfig"('ppe');
select "initGraphicImageConfig"('product');
使用java代码整合到spring中进行设置
在FileServerWebApp中整合。
注意,因为要用到crypto插件,所以,也要配置crypto插件的:扫描二维码关注公众号,回复: 5140075 查看本文章
BeanConfiguration下面添加:
package net.w2p.local.plugins.BeanConfiguration;
import com.xxl.conf.core.XxlConfClient;
import net.w2p.WebExt.Plugins.CryptoPlugin;
import net.w2p.WebExt.config.CryptoConf;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/***
*
* 系统加解密插件配置
* ***/
@Configuration
public class CryptoConfiguration {
@Bean(name="cryptoConf")
public CryptoConf cryptoConf(){
CryptoConf conf=new CryptoConf();
return conf;
}
@Bean(name="cryptoPlugin")
@Autowired
public CryptoPlugin cryptoPlugin(@Qualifier("cryptoConf") CryptoConf conf){
try {
CryptoPlugin plugin = new CryptoPlugin(conf);
return plugin;
}
catch (Exception ed){
ed.printStackTrace();
return null;
}
}
}
package net.w2p.local.plugins.BeanConfiguration;
import com.xxl.conf.core.XxlConfClient;
import com.xxl.conf.core.listener.XxlConfListener;
import net.w2p.Shared.common.WebTools;
import net.w2p.WebExt.Plugins.CryptoPlugin;
import net.w2p.WebExt.Plugins.DayuSmsPlugin;
import net.w2p.WebExt.Plugins.GraphicImagePlugin;
import net.w2p.WebExt.config.DaYuConf;
import net.w2p.WebExt.config.GraphicImageConf;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/****
*
* 整合阿里大鱼短信服务
*
* ****/
@Configuration
public class GraphicImageConfiguration {
@Bean(name="imgConf")
public GraphicImageConf imgConf(){
final GraphicImageConf conf=new GraphicImageConf();
return conf;
}
@Bean(name="imagePlugin")
@Autowired
public GraphicImagePlugin imagePlugin(@Qualifier("imgConf")GraphicImageConf conf,
@Qualifier("cryptoPlugin")CryptoPlugin cryptoPlugin){
try {
GraphicImagePlugin plugin = new GraphicImagePlugin(conf,cryptoPlugin);
return plugin;
}
catch (Exception ed){
ed.printStackTrace();
return null;
}
}
}
进行测试
图片准备
注意,这次的测试没那么简单,需要配置一下测试环境,譬如,配置水印文件位置等等。下面说明一下。
在
有测试用到的图片:
logo.png为水印,而demo2.jpg是测试用图片:
配置中心配置水印
如下图:
开启水印
设置水印地址
编写测试代码
测试代码如下:
package other;
import com.alibaba.fastjson.JSONObject;
import main.BaseTest;
import net.w2p.Shared.common.OpResult;
import net.w2p.Shared.path.WebRoot;
import net.w2p.WebExt.Plugins.DayuSmsPlugin;
import net.w2p.WebExt.Plugins.GraphicImagePlugin;
import net.w2p.WebExt.vo.ThumbnailResult;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
public class ExtComponentTest extends BaseTest {
@Autowired
GraphicImagePlugin imagePlugin;
@Test
public void testImagePlugin() throws Exception{
String demoPic="/home/too-white/图片/demos/demo2.jpg";
byte[] fileContent=FileUtils.readFileToByteArray(new File(demoPic));
ThumbnailResult result=imagePlugin.handle(fileContent);
ArrayList<byte[]> resContentList=new ArrayList<>();
resContentList.add(result.small.fileContent);
resContentList.add(result.medium.fileContent);
resContentList.add(result.large.fileContent);
ArrayList<File> outputFiles=new ArrayList<>();
outputFiles.add(new File("/home/too-white/图片/demos/small.jpg"));
outputFiles.add(new File("/home/too-white/图片/demos/medium.jpg"));
outputFiles.add(new File("/home/too-white/图片/demos/large.jpg"));
for(int i=0;i<3 ;i++){
File tmpFile=outputFiles.get(i);
if(!tmpFile.exists()){
tmpFile.createNewFile();
}
FileUtils.writeByteArrayToFile(tmpFile,resContentList.get(i));
}
}
}
执行结果
查看目标目录:
图片处理插件整合成功。
结语
图片处理一直是web项目的一个难点。
一个稳定的插件不经过长时间运行是不会完善的。估计这个插件有的是bug。