1、代码上传图片成功,浏览器直接访问下载问题:
(1)使用三级域名;
(2)指定上传文件的Content-Type(OSS jar包版本可能不一致,对号入座):
ObjectMetadata objectMeta = new ObjectMetadata();
objectMeta.setContentType("image/jpg");//在metadata中标记文件类型
objectMeta.setContentLength(out.toByteArray().length);
若在阿里云中设置,则点击文件右键设置HTTP头即可:
2、关于图片上传的显示:
图片路径+?x-oss-process=image/resize,m_fill,h_100,w_100 //可指定访问压缩尺寸的图片
图片路径+?x-oss-process=image/quality,q_20 //按像素压缩访问的图片
上述这些,可以用来对于已压缩上传图片,需要在app中显示时进一步调整。
不过,阿里云文档并没有提供压缩上传的功能,只针对在云上的图片显示做了很多丰富的处理。
3、图片上传压缩(参考一些上传,可以使用的)
第一次使用的是Thumbnailator,但不知道为什么不管怎么修改outputQuality(0.25f)值,虽然压缩了,但设置0.2和0.3效果并没有区别大小都没有变。没有试过压缩尺寸,这个不行也就没有再试了。
(1)原尺寸不变减少分辨率(对于大图片并不提倡,因为在手机上不忍直视,试过5M的,虽然压缩的可以,但失真严重,下面的方法对于png图片不可以,需要转换,暂时没有解决办法
https://stackoverflow.com/questions/15318677/how-do-i-write-a-bufferedimage-as-a-png-with-no-compression )
public class Test {
public static void main(String[] args) throws IOException {
String endpoint = "";
String accessKeyId = "";
String accessKeySecret = "";
String bucketName = "";//实际
//key
String key = "images/23_iso100_14mm6.jpg";
InputStream fileStream = new FileInputStream("D:/23_iso100_14mm.jpg");
ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
byte[] buff = new byte[10485760]; //暂时上限10M
int rc = 0;
while ((rc = fileStream.read(buff, 0, 10485760)) > 0) {
swapStream.write(buff, 0, rc);
}
byte[] tempByte = compressPicByQuality(swapStream.toByteArray(), 0.2f);
InputStream sbs = new ByteArrayInputStream(tempByte);
OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
ObjectMetadata objectMeta = new ObjectMetadata();
objectMeta.setContentType("image/jpg");//在metadata中标记文件类型
objectMeta.setContentLength(tempByte.length);
ossClient.putObject(bucketName, key, sbs,objectMeta);
}
/**
* @Title: compressPicByQuality @Description: 压缩图片,通过压缩图片质量,保持原图大小 @param quality:0-1 @return byte[] @throws
*/
public static byte[] compressPicByQuality(byte[] imgByte, float quality) {
byte[] inByte = null;
try {
ByteArrayInputStream byteInput = new ByteArrayInputStream(imgByte);
BufferedImage image = ImageIO.read(byteInput);
// 如果图片空,返回空
if (image == null) {
return null;
}
// 得到指定Format图片的writer
Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpg");// 得到迭代器,jpg,jpeg
ImageWriter writer = (ImageWriter) iter.next(); // 得到writer
// 得到指定writer的输出参数设置(ImageWriteParam )
//ImageWriteParam iwp = writer.getDefaultWriteParam();
ImageWriteParam iwp = new JPEGImageWriteParam(null);
//ImageWriteParam iwp = new P
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // 设置可否压缩
iwp.setCompressionQuality(quality); // 设置压缩质量参数
iwp.setProgressiveMode(ImageWriteParam.MODE_DISABLED);
ColorModel colorModel = ColorModel.getRGBdefault();
// 指定压缩时使用的色彩模式
iwp.setDestinationType(
new javax.imageio.ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel(16, 16)));
// 开始打包图片,写入byte[]
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // 取得内存输出流
IIOImage iIamge = new IIOImage(image, null, null);
// 此处因为ImageWriter中用来接收write信息的output要求必须是ImageOutput
// 通过ImageIo中的静态方法,得到byteArrayOutputStream的ImageOutput
writer.setOutput(ImageIO.createImageOutputStream(byteArrayOutputStream));
writer.write(null, iIamge, iwp);
inByte = byteArrayOutputStream.toByteArray();
} catch (IOException e) {
System.out.println("write errro");
e.printStackTrace();
}
return inByte;
}
}
(2)改变尺寸压缩(比较好些,暂时使用,不过对于png图片来说,压缩困难,有专门的国外付费软件,暂不考虑,下面会有jpg和png压缩后的比较,清晰度都还行)
public class Test {
public static void main(String[] args) throws IOException {
String endpoint = "";
String accessKeyId = "";
String accessKeySecret = "";
String bucketName = "";
//key
String key = "23_iso100_14mm6.jpg";
InputStream fileStream = new FileInputStream("D:/23_iso100_14mm.jpg");
ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
byte[] buff = new byte[10485760]; //暂时上限10M
int rc = 0;
while ((rc = fileStream.read(buff, 0, 10485760)) > 0) {
swapStream.write(buff, 0, rc);
}
ByteArrayInputStream in = new ByteArrayInputStream(swapStream.toByteArray()); //将b作为输入流;
BufferedImage image = ImageIO.read(in);
//1500 1500 jpg 268kb png 2.27M
//1000 1000 jpg 125kb png 1.27M(还是比较大的)
ArrayList<Integer> arrayList = getAutoWidthAndHeight(image,1000,1000);
int w = arrayList.get(0);
int h = arrayList.get(1);
Image newImage = image.getScaledInstance(w, h,Image.SCALE_DEFAULT);
BufferedImage outputImage = new BufferedImage(w, h,BufferedImage.TYPE_INT_RGB);
Graphics2D g = outputImage.createGraphics();
g.drawImage(newImage, 0, 0, null); // 绘制缩小后的图
g.dispose();
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(outputImage,"jpg",out);
InputStream sbs = new ByteArrayInputStream(out.toByteArray());
OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
ObjectMetadata objectMeta = new ObjectMetadata();
objectMeta.setContentType("image/jpg");//在metadata中标记文件类型
objectMeta.setContentLength(out.toByteArray().length);
ossClient.putObject(bucketName, key, sbs,objectMeta);
}
/***
*
* @param bufferedImage 要缩放的图片对象
* @param width_scale 要缩放到的宽度
* @param height_scale 要缩放到的高度
* @return 一个集合,第一个元素为宽度,第二个元素为高度
*/
public ArrayList<Integer> getAutoWidthAndHeight(BufferedImage bufferedImage,int width_scale,int height_scale){
ArrayList<Integer> arrayList = new ArrayList<Integer>();
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
if(width<=1000&&height<=1000){//限制不压缩(简陋版。。)
arrayList.add(width);
arrayList.add(height);
}else{
double scale_w =getDot2Decimal( width_scale,width);
System.out.println("getAutoWidthAndHeight width="+width + "scale_w="+scale_w);
double scale_h = getDot2Decimal(height_scale,height);
if (scale_w<scale_h) {
arrayList.add(parseDoubleToInt(scale_w*width));
arrayList.add(parseDoubleToInt(scale_w*height));
}
else {
arrayList.add(parseDoubleToInt(scale_h*width));
arrayList.add(parseDoubleToInt(scale_h*height));
}
}
return arrayList;
}
}