瀏覽代碼

商品资料水印添加

Aslee 3 年之前
父節點
當前提交
4357684d41

+ 32 - 21
src/main/java/com/caimei/modules/archive/service/CmProductArchiveContentService.java

@@ -84,7 +84,7 @@ public class CmProductArchiveContentService extends CrudService<CmProductArchive
 							e.printStackTrace();
 						}
 						image.setOssUrl(imageUrl);
-						Map<String, Object> map = WaterMarkUtils.addWaterMark(null, null, imageUrl, "img");
+						Map<String, Object> map = WaterMarkUtils.addWaterMark(null, null, imageUrl, "img", null);
 						if (null != map) {
 							String ossName = (String)map.get("ossName");
 							String waterUrl = (String) map.get("imagePath");
@@ -145,29 +145,39 @@ public class CmProductArchiveContentService extends CrudService<CmProductArchive
         Map<String, Object> map = new HashMap<>();
         String fileAllName = multipartFile.getOriginalFilename();
         String fileType = fileAllName.substring(fileAllName.lastIndexOf(".") + 1);
-		String fileShortName = fileAllName.substring(0, fileAllName.lastIndexOf("."));
-        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
-        String filePath = uuid + "." + fileType;
-        String contentType = OssArchiveUtil.getContentType(fileAllName);
-        try {
-            //保存本地
-            File file = OssArchiveUtil.ossUpload(multipartFile);
+		String uuid1 = UUID.randomUUID().toString().replaceAll("-", "");
+		String filePath1 = uuid1 + "." + fileType;
+		String uuid2 = UUID.randomUUID().toString().replaceAll("-", "");
+		String filePath2 = uuid2 + "." + fileType;
+		String contentType = OssArchiveUtil.getContentType(fileAllName);
+		try {
+			//保存本地
+			File file = OssArchiveUtil.ossUpload(multipartFile);
 			logger.info("默认路径>>>" + file.getAbsolutePath());
 			String contentDispositon = "pdf".equals(fileType) ? "inline" : "attachment";
-			//上传oss
-			String url = OssArchiveUtil.ossUpload(filePath, "archiveFile/", file, contentType, contentDispositon);
+			// 源文件上传oss
+			String url = OssArchiveUtil.ossUpload(filePath1, "archiveFile/", file, contentType, contentDispositon);
+			// 添加水印
+			WaterMarkUtils.addWaterMark(file, "采美365网", filePath2, fileType, url);
+			File waterMarkFile = new File(tempPath + filePath2);
+			//水印文件上传oss
+			String waterMarkUrl = OssArchiveUtil.ossUpload(filePath2, "archiveFile/", waterMarkFile, contentType, contentDispositon);
+			logger.info(">>>>>>>>>>>>>>>>>" + waterMarkUrl);
 			//删除本地文件
 			OssArchiveUtil.deleteFile(file);
-            //保存关联关系
-            CmProductArchiveFile archiveFile = new CmProductArchiveFile();
-            archiveFile.setFileName(fileName);
-            archiveFile.setOssName(filePath);
-            archiveFile.setOssUrl(url);
-            archiveFile.setUploadTime(new Date());
-            cmProductArchiveContentDao.insertFile(archiveFile);
-            map.put("success", true);
-            map.put("msg", "操作成功");
-            map.put("archiveFile", archiveFile);
+//			OssArchiveUtil.deleteFile(waterMarkFile);
+			//保存关联关系
+			CmProductArchiveFile archiveFile = new CmProductArchiveFile();
+			archiveFile.setFileName(fileName);
+			archiveFile.setOssName(filePath1);
+            archiveFile.setWaterOssName(filePath2);
+			archiveFile.setOssUrl(url);
+            archiveFile.setWaterOssUrl(waterMarkUrl);
+			archiveFile.setUploadTime(new Date());
+			cmProductArchiveContentDao.insertFile(archiveFile);
+			map.put("success", true);
+			map.put("msg", "操作成功");
+			map.put("archiveFile", archiveFile);
         } catch (Exception e) {
             e.printStackTrace();
             map.put("success", false);
@@ -175,6 +185,7 @@ public class CmProductArchiveContentService extends CrudService<CmProductArchive
             logger.info("上传异常!!!");
         }
         return map;
+
     }
 
 
@@ -192,7 +203,7 @@ public class CmProductArchiveContentService extends CrudService<CmProductArchive
 			//保存本地
 			File file = OssArchiveUtil.ossUpload(multipartFile);
 			logger.info("默认路径>>>" + file.getAbsolutePath());
-			WaterMarkUtils.addWaterMark(file, "采美365网", filePath_2, fileType);
+			WaterMarkUtils.addWaterMark(file, "采美365网", filePath_2, fileType, null);
 			File waterMarkFile = new File(tempPath + filePath_2);
 			String contentDispositon = "pdf".equals(fileType) ? "inline" : "attachment";
 			//上传oss

+ 51 - 0
src/main/java/com/caimei/modules/archive/utils/CmdExecuter.java

@@ -0,0 +1,51 @@
+package com.caimei.modules.archive.utils;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.LinkedList;
+import java.util.List;
+
+public class CmdExecuter {
+    public static String exec(List<String> cmd) {
+        String converted_time = null;
+        Process proc = null;
+        BufferedReader stdout = null;
+        try {
+            ProcessBuilder builder = new ProcessBuilder();
+            builder.command(cmd);
+            builder.redirectErrorStream(true);
+            proc = builder.start();
+            stdout = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+            String line;
+            int lineNumber = 1;
+            List<String> returnStringList = new LinkedList<String>();
+            while ((line = stdout.readLine()) != null) {
+                System.out.println("第" + lineNumber + "行:" + line);
+                lineNumber = lineNumber + 1;
+                returnStringList.add(FFMPEG.dealString(line));
+            }
+            String info = "";
+            for (int i = returnStringList.size() - 1; i >= 0; i--) {
+                if (null != returnStringList.get(i) && returnStringList.get(i).startsWith("frame=")) {
+                    info = returnStringList.get(i);
+                    break;
+                }
+            }
+            if (null != info) {
+                converted_time = info.split("time=")[1].split("bitrate=")[0].trim();
+            }
+        } catch (IndexOutOfBoundsException ex) {
+            converted_time = null;
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                proc.waitFor();
+                stdout.close();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return converted_time;
+    }
+}

+ 219 - 0
src/main/java/com/caimei/modules/archive/utils/FFMPEG.java

@@ -0,0 +1,219 @@
+package com.caimei.modules.archive.utils;
+
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.util.StringUtils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class FFMPEG {
+
+    public static String dealString(String str) {
+        Matcher m = Pattern.compile("^frame=.*").matcher(str);
+        String msg = "";
+        while (m.find()) {
+            msg = m.group();
+        }
+        return msg;
+    }
+
+    /**
+     * 如果是数字就是成功的时间(秒数)
+     *
+     * @param str
+     * @return
+     */
+    public static boolean isNumeric(String str) {
+        Pattern pattern = Pattern.compile("[0-9]*");
+        Matcher isNum = pattern.matcher(str);
+        if (!isNum.matches()) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 如果返回不是null的值就是成功(值为转换用时单位:秒)
+     *
+     * @param instr
+     * @return
+     */
+    public static String returnSecond(String instr) {
+        String returnValue = null;
+        if (null != instr) {
+            String[] a = instr.split("\\.");
+            String[] b = a[0].split(":");
+            int returnNumber = 0;
+            if (null != instr && b[0].length() != 0) {
+                returnNumber = Integer.valueOf(b[0]) * 60 * 60 + Integer.valueOf(b[1]) * 60 + Integer.valueOf(b[2]);
+                returnValue = String.valueOf(returnNumber);
+            } else {
+                returnValue = null;
+            }
+        }
+        return returnValue;
+    }
+
+    /**
+     * 获取视频格式(转码前的格式和转码后的格式都可以调用)
+     *
+     * @param outputPath
+     * @return
+     */
+    public static String returnVideoFormat(String outputPath) {
+        return outputPath.substring(outputPath.lastIndexOf(".") + 1);
+    }
+
+    /**
+     * @ HashMap<String,String> dto 参数传递对象<br>
+     * dto中包含的参数<br>
+     * (必填)1.ffmpeg_path:ffmpeg执行文件地址,如 d:\\ffmpeg\\ffmpeg.exe Linux下直接调用ffmpeg命令(当然你事先已经有这个程序了)<br>
+     * (必填)2.input_path:原视频路径<br>
+     * (必填)3.video_converted_path:转换后视频输出路径<br>
+     * (可选)4.screen_size:视频尺寸 长度乘宽度 乘号用英文小写"x"如 512x480<br>
+     * (可选)5.logo:水印地址(其实在ffmpeg中有一个专门的watermark参数,logo跟它有何不同,我还没看,不过对我来说效果一样 貌似需要png图片才行)<br>
+     * (可选,如果填写必须有logo才行,默认为0)6.xaxis:水印logo的横坐标(只有logo参数为一个正确路径才行) 比如0<br>
+     * (可选,如果填写必须有logo才行,默认为0)6.yaxis:水印logo的纵坐标(只有logo参数为一个正确路径才行) 比如0<br>
+     * (可选)vb:视频比特率,传入一个数值,单位在程序里面拼接了k
+     * (可选)ab:音频比特率,传入一个数值,单位在程序里面拼接了k
+     */
+    public String videoTransfer(HashMap<String, String> dto) {
+        // String ffmpeg_path,String input_path,String video_converted_path,String logo,String screen_size,String xaxis,String yaxis,String vb,String ab
+        List<String> cmd = new ArrayList<String>();
+        cmd.add(dto.get("ffmpeg_path"));
+        cmd.add("-y");
+        cmd.add("-i");
+        cmd.add(dto.get("input_path"));
+        if (null != dto.get("screen_size")) {
+            cmd.add("-s");
+            cmd.add(dto.get("screen_size"));
+        }
+        int markHeight= 50;
+        int markWidth = 50;
+        if (!StringUtils.isEmpty(dto.get("width")) ) {
+            markHeight = (int) (Integer.parseInt(dto.get("width")) * 0.1);
+            markWidth = markHeight;
+        }
+        if (null != dto.get("logo")) {
+            String logo = dto.get("logo");
+            cmd.add("-vf");
+            String xaxis = dto.get("xaxis");
+            String yaxis = dto.get("yaxis");
+            xaxis = xaxis != null && !xaxis.equals("") ? xaxis : "0";
+            yaxis = yaxis != null && !yaxis.equals("") ? yaxis : "0";
+
+//            String logoString = "movie=" + logo + "[logo],[in][logo]overlay=x=" + xaxis + ":y=" + yaxis + "[out]";
+            String logoString = "movie=" + logo + ",scale=" + markHeight + ":" + markWidth + "[watermark],[in][watermark]overlay=x=" + xaxis + ":y=" + yaxis + "[out]";
+//            String logoString = "movie=" + logo + ",scale=" + 30 + ":" + 30 + "[watermark];[in][watermark]overlay=main_w-overloay_w-10:10[out]";
+            cmd.add(logoString);
+        }
+        cmd.add("-strict");
+        cmd.add("-2");
+        if (null != dto.get("vb") && !dto.get("vb").equals("")) {
+            cmd.add("-vb");
+            cmd.add(dto.get("vb") + "k");
+        }
+        if (null != dto.get("ab") && !dto.get("ab").equals("")) {
+            cmd.add("-ab");
+            cmd.add(dto.get("ab") + "k");
+        }
+        cmd.add("-q:v");
+        cmd.add("4");
+        cmd.add(dto.get("video_converted_path"));
+        String converted_time = CmdExecuter.exec(cmd);
+        //获取转换时间
+        return returnSecond(converted_time);
+    }
+
+    public static Map<String, Object> setVideoWaterMark(String fileUrl, String filePath) {
+        HashMap<String, String> dto = new HashMap<String, String>();
+        //必填
+        dto.put("ffmpeg_path", "D:\\workSoftWare\\ffmpeg\\bin\\ffmpeg.exe");
+        //必填
+        dto.put("input_path", fileUrl);
+//        dto.put("input_path", "D:\\WorkSpace\\file\\video.mp4");
+        //必填
+        dto.put("video_converted_path", filePath);
+        //可选(注意windows下面的logo地址前面要写4个反斜杠,如果用浏览器里面调用servlet并传参只用两个,如 d:\\:/ffmpeg/input/logo.png)
+        try {
+            ClassPathResource classPathResource = new ClassPathResource("/templates/images/imgWaterMark.png");
+            dto.put("logo", classPathResource.getURL().toString());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        //logo X坐标
+        dto.put("xaxis", "30");
+        //logo Y坐标
+        dto.put("yaxis", "30");
+        Map<String, String> videoSize = new FFMPEG().getVideoSize(dto);
+        //长度
+        dto.put("height", videoSize.get("height"));
+        //宽度
+        dto.put("width", videoSize.get("width"));
+
+        String secondsString = new FFMPEG().videoTransfer(dto);
+        System.out.println("转换共用:" + secondsString + "秒");
+
+        return null;
+    }
+
+    /**
+     * 获取视频长宽
+     * @param dto
+     * @return
+     */
+    public Map<String,String> getVideoSize(HashMap<String, String> dto) {
+        Map<String, String> map = new HashMap<>(2);
+        List<String> cmd = new ArrayList<String>();
+        cmd.add(dto.get("ffmpeg_path"));
+        cmd.add("-i");
+        cmd.add(dto.get("input_path"));
+        String height = "";
+        String width = "";
+        try {
+            ProcessBuilder builder = new ProcessBuilder();
+            builder.command(cmd);
+            final Process p = builder.start();
+            //从输入流中读取视频信息
+            BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
+            StringBuffer sb = new StringBuffer();
+            String line = "";
+            while ((line = br.readLine()) != null) {
+                sb.append(line);
+            }
+            br.close();
+            System.out.println(sb.toString());
+
+            int start = sb.indexOf("Video:");
+            String substring = sb.substring(start);
+            String[] split = substring.split("\\),");
+            String sb1 = "";
+            String sizeStr = "";
+            if (split.length > 3) {
+                sb1 = split[2];
+            }
+            String[] split1 = sb1.split(",");
+            if (split1.length > 0) {
+                sizeStr = split1[0];
+            }
+            String[] xes = sizeStr.split("x");
+            if (xes.length > 1) {
+                height = xes[0].trim();
+                width = xes[1].trim();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        map.put("height", height);
+        map.put("width", width);
+        return map;
+    }
+
+}

+ 4 - 2
src/main/java/com/caimei/modules/archive/utils/WaterMarkUtils.java

@@ -324,7 +324,7 @@ public class WaterMarkUtils {
         for (int i = 1; i < total; i++) {
             //在内容上方加水印
             content = stamper.getOverContent(i);
-            gs.setFillOpacity(0.5f);
+            gs.setFillOpacity(0.2f);
             content.saveState();
             content.setGState(gs);
             content.beginText();
@@ -669,7 +669,7 @@ public class WaterMarkUtils {
         return image;
     }
 
-    public static Map<String,Object> addWaterMark(File inputFile, String markStr, String filePath, String fileType) {
+    public static Map<String, Object> addWaterMark(File inputFile, String markStr, String filePath, String fileType, String fileUrl) {
         if (fileType.contains("doc")) {
             setWordWaterMark(inputFile, markStr, filePath, fileType);
         } else if (fileType.contains("ppt")) {
@@ -678,6 +678,8 @@ public class WaterMarkUtils {
             setPdfWatermark(inputFile, filePath, markStr);
         } else if (fileType.contains("img")) {
             return setImageWaterMark(filePath);
+        } else if (fileType.contains("mp4")) {
+            return FFMPEG.setVideoWaterMark(fileUrl, outPath + filePath);
         }
         return null;
     }

+ 1 - 1
src/main/resources/mappings/modules/archive/CmProductArchiveContentMapper.xml

@@ -8,7 +8,7 @@
 		a.title AS "title",
 		a.type AS "type",
 		a.addTime AS "addTime",
-		cf.ossName,
+		cf.waterOssName as ossName,
 		cf.fileName,
 		cf.uploadTime,
 		cf.ossUrl

+ 1 - 0
src/main/resources/mappings/modules/hehe/CmHeheCouponMapper.xml

@@ -64,6 +64,7 @@
 				ORDER BY ${page.orderBy}
 			</when>
 			<otherwise>
+				order by a.createDate desc
 			</otherwise>
 		</choose>
 	</select>

二進制
src/main/resources/templates/images/caimeiLogo.png


二進制
src/main/resources/templates/images/caimeiLogo2.png


+ 2 - 3
src/main/webapp/WEB-INF/views/modules/archive/addFileForm.jsp

@@ -224,7 +224,6 @@
 
         //点击上传按钮后上传文件
         $('#addSubmit').click(function () {
-            debugger
             var filesById = document.getElementById('archiveFile');
             var files = $('#archiveFile');
             var fileList = files.prop('files');
@@ -238,8 +237,8 @@
             data.append('fileName', fileName);
             $('.upload-loading').css("display", "inline");
             $.ajax({
-                url: "${ctx}/archive/cmProductArchiveContent/addWaterMark",
-                <%--url: "${ctx}/archive/cmProductArchiveContent/upload",--%>
+                <%--url: "${ctx}/archive/cmProductArchiveContent/addWaterMark",--%>
+                url: "${ctx}/archive/cmProductArchiveContent/upload",
                 data: data,
                 type: "POST",
                 processData: false,

+ 1 - 0
src/main/webapp/WEB-INF/views/modules/hehe/cmHeheCouponList.jsp

@@ -31,6 +31,7 @@
 	<form:form id="searchForm" modelAttribute="cmHeheCoupon" action="${ctx}/hehe/cmHeheCoupon/" method="post" class="breadcrumb form-search">
 		<input id="pageNo" name="pageNo" type="hidden" value="${page.pageNo}"/>
 		<input id="pageSize" name="pageSize" type="hidden" value="${page.pageSize}"/>
+		<form:hidden path="couponType" />
 		<div class="ul-form">
 			 <label>优惠券名称:</label>
 				<form:input path="name" htmlEscape="false" maxlength="50" class="input-medium"/>