1.jar包(maven仓库没有依赖,本地引入)
2.编写OosClientConfig
package com.kuyuntech.appraisal.appraisalplatform.configuration.core;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.S3ClientOptions;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class OosClientConfig {
public static final String accessKey = "099dce14a34f6f40****";
public static final String secretKey = "138f54d13d3b5f94038bad25946c061787dc****";
public static final String endpoint = "oos-hazz.ctyunapi.cn"; //这个有效
public static final String bucket = "appra****";
@Bean
public AmazonS3 oosClient() {
ClientConfiguration clientConfig = new ClientConfiguration();
// 设置连接的超时时间,单位毫秒
clientConfig.setConnectionTimeout(30 * 1000);
// 设置 socket 超时时间,单位毫秒
clientConfig.setSocketTimeout(30 * 1000);
clientConfig.setProtocol(Protocol.HTTP); //设置 http
// 设置 V4 签名算法中负载是否参与签名,关于签名部分请参看《OOS 开发者文档》
S3ClientOptions options = new S3ClientOptions();
options.setPayloadSigningEnabled(true);
// 创建 client
AmazonS3 oosClient = new AmazonS3Client(
new PropertiesCredentials(accessKey, secretKey), clientConfig);
// 设置 endpoint
oosClient.setEndpoint(endpoint);
//设置选项
oosClient.setS3ClientOptions(options);
return oosClient;
}
}
3.1Oss上传文件代码(InputStream)
AmazonS3 ossClient = oosClientConfig.oosClient();
// 创建上传Object的Metadata
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setCacheControl("no-cache");
objectMetadata.setHeader("Pragma", "no-cache");
String path = multipartFile.getOriginalFilename();
try {
objectMetadata.setContentLength(inputStream.available());
ossClient.putObject(bucket, path, inputStream, objectMetadata);
String url = generatePresignedUrl(path);
pathUrl = url;
} catch (Exception e) {
logger.error("上传文件到oos失败", e);
return ResponseBean.serverError("上传文件到oos失败");
} finally {
if (ossClient != null) {
((AmazonS3Client) ossClient).shutdown();
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.2生成访问url
/**
* @Desecription: 获取文件下载地址 ,并设置过期时间
*/
public String generatePresignedUrl(String fileKey) throws ParseException {
GeneratePresignedUrlRequest request = new
GeneratePresignedUrlRequest(bucket, fileKey);
//设置过期时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date expireDate = sdf.parse("2031-01-01");
request.setExpiration(expireDate);
URL url = oosClientConfig.oosClient().generatePresignedUrl(request);
return url.toString();
}
4.1图片压缩
String originalFilename = multipartFile.getOriginalFilename();
//视频
if (originalFilename != null && originalFilename.toLowerCase().endsWith(".mp4")) {
//不能超过200M
long fileSizeInBytes = multipartFile.getSize();
double fileSizeInMB = (double) fileSizeInBytes / (1024 * 1024); // 转换为MB
if (fileSizeInMB > 200) {
return ResponseBean.serverError("视频不可以超过200MB");
}
try {
inputStream = multipartFile.getInputStream();
//截取视频第一帧作为缩略图
videoUrl = XlUtil.getVideoSl(multipartFile.getInputStream());
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
//不能超过20M
long fileSizeInBytes = multipartFile.getSize();
double fileSizeInMB = (double) fileSizeInBytes / (1024 * 1024); // 转换为MB
if (fileSizeInMB > 20) {
return ResponseBean.serverError("图片不可以超过20MB");
}
//压缩图片
try {
ByteArrayOutputStream outputStreamut = new ByteArrayOutputStream();
inputStream = multipartFile.getInputStream();
// 获取原始图片的尺寸
BufferedImage originalImage = ImageIO.read(multipartFile.getInputStream());
int originalWidth = originalImage.getWidth();
int originalHeight = originalImage.getHeight();
if (originalWidth > 1920 || originalHeight > 1920) {
int targetWidth = Math.min(originalWidth, 1920);
int targetHeight = Math.min(originalHeight, 1920);
Thumbnails.of(inputStream)
.size(targetWidth, targetHeight)
.keepAspectRatio(true) //保持原始比例
.outputFormat("jpeg") // 设置输出格式为 JPEG,PNG格式无法压缩质量
.outputQuality(0.9f)
.toOutputStream(outputStreamut);
inputStream = new ByteArrayInputStream(outputStreamut.toByteArray());
} else {
// Thumbnails.of(inputStream)
// .scale(1f) // 值在0到1之间,1f就是原图大小,0.5就是原图的一半大小
// .outputQuality(1f) // 值也是在0到1,越接近于1质量越好,越接近于0质量越差
// .toOutputStream(outputStreamut);
// inputStream = new ByteArrayInputStream(outputStreamut.toByteArray());
}
} catch (IOException e) {
throw new RuntimeException(e);
}
//获取缩略图
if (StringUtils.isNotEmpty(isSl) && isSl.equals("yes")) {
pathUrl2 = XlUtil.getXlImg(multipartFile.getInputStream());
}
if (StringUtils.isNotEmpty(isSY) && isSY.equals("yes")) {
//添加水印
inputStream = fileService.handleRemix(inputStream);
}
}
4.2图片压缩依赖
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
<dependency>
<groupId>org.sejda.imageio</groupId>
<artifactId>webp-imageio</artifactId>
<version>0.1.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
5.1获取视频缩略图
//获取视频缩略图
public static String getVideoSl(InputStream inputStream) {
InputStream slInputStream = null;
String xlUrl = null;
try {
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputStream);
grabber.start();
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage firstFrame = converter.convert(grabber.grabImage());
grabber.stop();
if (firstFrame != null) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
ImageIO.write(firstFrame, "jpg", outputStream);
byte[] imageBytes = outputStream.toByteArray();
slInputStream = new ByteArrayInputStream(imageBytes);
AmazonS3 ossClient = oosClientConfig.oosClient();
// 创建上传Object的Metadata
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setCacheControl("no-cache");
objectMetadata.setHeader("Pragma", "no-cache");
String path = UUID.randomUUID().toString().replace("-", "") + ".jpg";
try {
objectMetadata.setContentLength(slInputStream.available());
ossClient.putObject(bucket, path, slInputStream, objectMetadata);
String url = generatePresignedUrl(path);
xlUrl = url;
return xlUrl;
} catch (Exception e) {
return null;
} finally {
if (ossClient != null) {
((AmazonS3Client) ossClient).shutdown();
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
5.2视频缩略图依赖
<!--视频缩略图-->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg-platform</artifactId>
<version>4.4-1.5.6</version>
</dependency>
6图片添加水印(从OSS获取图片进行合成,加水印会压缩图片)
//添加水印
public InputStream handleRemix(InputStream inputStream) {
//获取logo图片
byte[] bytes = HttpUtil.sendGetLogo();
ByteArrayInputStream logoStream = new ByteArrayInputStream(bytes);
ByteArrayOutputStream outputStreamRemix = new ByteArrayOutputStream();
// 获取上传的图片和logo图片
try {
BufferedImage uploadImage = ImageIO.read(inputStream);
BufferedImage logoImage = ImageIO.read(logoStream);
// 创建一个新的合成图片,大小和上传图片一样
BufferedImage combinedImage = new BufferedImage(uploadImage.getWidth(), uploadImage.getHeight(), BufferedImage.TYPE_INT_RGB);
// 获取合成图片的 Graphics2D 对象
Graphics2D g2d = combinedImage.createGraphics();
// 将上传的图片绘制到合成图片上
g2d.drawImage(uploadImage, 0, 0, null);
// 将logo图片绘制到合成图片的左下角
int wh = uploadImage.getHeight() > uploadImage.getWidth() ? uploadImage.getWidth() : uploadImage.getHeight();
int height = combinedImage.getHeight();
int logoWidth = wh / 9;
int logoHeight = (wh / 9) / 3;
int x = 20; // 左下角的 x 坐标
int y = combinedImage.getHeight() - logoHeight - 20; // 左下角的 y 坐标
g2d.drawImage(logoImage, x, y, logoWidth, logoHeight, null);
// 释放 Graphics2D 资源
g2d.dispose();
// 将合成图片写入 ByteArrayOutputStream
ImageIO.write(combinedImage, "jpg", outputStreamRemix);
} catch (IOException e) {
e.printStackTrace();
}
return new ByteArrayInputStream(outputStreamRemix.toByteArray());
}