记录自己在Java开发过程中遇到的图形处理的问题。
本次开发的需求,要求画图,输出的图片格式为bmp,分辨率达到600DPI,且图片位深度为24位。
问题描述:Java的输出的图片默认为72DPI,用BufferedImage需要设定像素宽高,即h/w = DPI * (图片宽/高) /25.4 。像素宽高是基于600dpi计算出来的,因为dpi变小了,导致输出的图片实际宽高增大,图片就变得非常的大。
ImageWriter可以对JPEG和PNG格式的图片进行DPI的设置,但是对输出BMP格式的图片,无法进行宽高设置外的操作,BMPMetaData表示 readonly = true。
Java无法重新设置BMP格式文件输出的DPI,只有寻找其他办法来解决。
DPI解决方法:
找到了一个处理工具commons-imaging,Maven仓库就有。只需要配置PIXEL_DENSITY一个参数就可以确定输出图片的DPI。
public static void writeImage(BufferedImage bufferedImage, String filePath, ImageFormat imageFormat, double DPI) {
Map<String,Object> map = new HashMap<>();
PixelDensity pixelDensity = PixelDensity.createFromPixelsPerInch(DPI,DPI);
map.put("PIXEL_DENSITY", pixelDensity);
//map.put("FORMAT","bmp");
File file = new File(filePath);
if(!file.getParentFile().exists())
file.getParentFile().mkdirs();
try(OutputStream outputStream = new FileOutputStream(filePath)) {
Imaging.writeImage(bufferedImage,outputStream, imageFormat,map);
//parser.writeImage(bufferedImage,outputStream,map);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException | ImageWriteException e) {
e.printStackTrace();
}
}
DPI问题解决好了,遇到了第二个问题,图片要上传的系统要求图片必须是24位的图片,使用commons-imaging输出的bmp图片是8位深度的,工具本身也没有处理位深度的内容。
辗转又找到了一个图形处理工具,GraphicsMagick。这款工具需要安装到本地,可以通过DOS命令处理图片,也提供编程接口,使开发者可以在程序中调用。
public static void tranPicByGM(String filePath,int height,int width) throws InterruptedException, IOException, IM4JavaException {
ConvertCmd cmd = new ConvertCmd(true);
cmd.setSearchPath(searchPath);
IMOperation op = new IMOperation();
String arg = (height-1)+"x"+(width-1);
op.addImage(filePath);//第一处是图片文件来源
op.addRawArgs("-colorspace","RGB");
op.addRawArgs("-resize",arg);
op.addImage(filePath);//第二处是输出的图片文件路径
cmd.run(op);
}
原本只是设置colorspace,但是发现输出的图片都转换成了32位。期间发现添加一下缩略裁剪(原本是只是设置一下剪裁,宽高还是使用的图片本身的大小。op.addRawArgs("-resize",height+"x"+width);),输出的图片可以变成24位了,但是只有一个样式的bmp转成了24位,其他样式的bmp都转换成 32位。本人段位太低,不太能研究出怎么回事。最后只能进行一点点的裁剪,对图片不会有多少影响的情况下,所有的bmp都成功的转换成24位了。
至此图片开发的问题算是解决好了。
在搬到服务器的时候遇到了点小问题。在linux中安装GraphicsMagick,要解压压缩包,网上前辈的教程说需要先安装对jpeg和png的插件,当然我的软件有处理png的地方用到了png,后面压缩图片的时候也用到了GraphicsMagick。
我当时以为服务器应该是支持jpeg和png的呀,结果直接走后面的安装过程,跑程序处理png 的时候出问题了——不支持png的转换(还是自己不太严谨。。。。。。)这时候再安装支持的插件,重新走一遍安装步骤就不行了,只能完全删了之后重新来一遍,不是像重新加载一下就OK的。
还是要老老实实跟着老师说的来做,不懂得不要自以为是的瞎搞了。