java操作FFmpeg处理图片
图片加水印:
import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import javax.imageio.ImageIO; public class ImageAddWatermarkUtil { public static void imageAddWatermark(String srcFileUrl) { File srcFolder = new File(srcFileUrl); // int i = 0; for (File file : srcFolder.listFiles()) { // File srcImgFile = new File(srcFileUrl);//得到文件 if (file.isFile() && file.getName().endsWith(".jpg")) { Image srcImg = null; try { srcImg = ImageIO.read(file); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } // 文件转化为图片 int srcImgWidth = srcImg.getWidth(null);// 获取图片的宽 int srcImgHeight = srcImg.getHeight(null);// 获取图片的高 // 加水印 Font font = new Font("微软雅黑", Font.PLAIN, 10); BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB); Graphics2D graphics2d = bufImg.createGraphics(); graphics2d.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null); graphics2d.setColor(Color.WHITE); // 设置水印颜色 graphics2d.setFont(font); // 设置字体 // 设置水印的坐标 String name = file.getName(); String waterMarkContent = name.substring(0, name.indexOf(".")); // System.out.println(getWatermarkLength(waterMarkContent, graphics2d)); int x = srcImgWidth - getWatermarkLength(waterMarkContent, graphics2d) - 3; int y = srcImgHeight - 3; graphics2d.drawString(waterMarkContent, x, y); // 画出水印 graphics2d.dispose(); // 输出图片 FileOutputStream outImgStream = null; try { outImgStream = new FileOutputStream(file); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { ImageIO.write(bufImg, "jpg", outImgStream); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { outImgStream.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { outImgStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public static int getWatermarkLength(String waterMarkContent, Graphics2D g) { return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length()); } public static void main(String[] args) { } }
图片合并:
import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class ImageMergeUtil { public static String mergeImage(String srcFileUrl, String size) { // BufferedImage image1 = ImageIO.read(file1); // BufferedImage image2 = ImageIO.read(file2); // String srcFileUrl = "D:\\cdv\\screenshot-test\\image-folder"; int counts = getFileCounts(srcFileUrl); String sizeString[] = size.split("x"); int width = Integer.valueOf(sizeString[0]); int height = Integer.valueOf(sizeString[1]); int totalHeight = 0; if (counts%5==0) totalHeight = height*counts/5; else totalHeight = height*counts/5 + 1; BufferedImage combined = new BufferedImage(width*5,totalHeight, BufferedImage.TYPE_INT_RGB); // paint both images, preserving the alpha channels Graphics2D graphics2d = combined.createGraphics(); File srcFolder = new File(srcFileUrl); int i = 0; for (File file : srcFolder.listFiles()) { if (file.isFile()&&file.getName().endsWith(".jpg")) { BufferedImage fileImage = null; try { fileImage = ImageIO.read(file); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } graphics2d.drawImage(fileImage, width*(i%5), height*(i/5), null); //删除已经加入照片文件 file.delete(); i++; } } // Save as new image File photoWallFolder = new File( srcFileUrl + "\\photoWall");// fisrcFileUrl + "\\photoWall"; if (!photoWallFolder.exists()) { photoWallFolder.mkdirs(); } File photoWallImage = new File(srcFileUrl + "\\photoWall", "photoWall.jpg"); int k = 0; while(photoWallImage.exists()) { photoWallImage = new File(srcFileUrl + "\\photoWall", "photoWall-" + String.valueOf(k++) + ".jpg"); } try { ImageIO.write(combined, "JPG", photoWallImage); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return photoWallImage.getAbsolutePath(); } public static int getFileCounts(String srcFileUrl) { int counts = 0; File fileList[] = new File(srcFileUrl).listFiles(); for (int i = 0; i < fileList.length; i++) { if (fileList[i].isFile()&&fileList[i].getName().endsWith(".jpg")) { counts++; } } //System.out.println(counts); return counts; } public static void main(String[] args) { String srcFileUrl = ""; mergeImage(srcFileUrl, "200x120"); } }
图片抽帧:
import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ScreenShotUtil { // private static Logger logger = LoggerFactory.getLogger(ScreenShotUtil.class); private static final Logger logger = LoggerFactory.getLogger(ScreenShotController.class); public static PointScreen shotByTimePoint(String screenshotEXEPath, String srcFileUrl, String timePoint, String size, String outUrl) { List<String> cmd = new LinkedList<String>(); cmd.add(screenshotEXEPath); // cmd.add("-y"); cmd.add("-i"); cmd.add(srcFileUrl); cmd.add("-ss"); cmd.add(timePoint); // cmd.add("-i"); // cmd.add(srcFileUrl); cmd.add("-t"); cmd.add("0.001"); cmd.add("-s"); cmd.add(size); cmd.add("-ignore-black"); cmd.add(outUrl + "\\temp\\.jpg"); // logger.debug("shotByTimePoint: " + cmd); // System.out.println(cmd); ProcessBuilder pb = new ProcessBuilder(); pb.command(cmd); File imageFolder = new File(outUrl + "\\temp"); imageFolder.mkdirs(); try { Process process = pb.start(); process.waitFor(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } File newImageFile = null; for (File imageFile : imageFolder.listFiles()) { String imageName = timePoint.replaceAll("[:|.]", "-"); newImageFile = new File(outUrl, imageName + ".jpg"); imageFile.renameTo(newImageFile); imageFile.delete(); } return new PointScreen(newImageFile.getAbsolutePath(), timePoint); } public static List<PointScreen> shotByKeyFrame(String screenshotEXEPath, String srcFileUrl, String size, String outUrl) { /** * 转场分析抽取若干张图片(输出名称包含百纳秒) snapshot -i oceans-clip.webm -scene_transition 1 * oceans-clip-%013d.jpg 输出例为 oceans-clip-0000000000123.jpg, * oceans-clip-0000000004567.jpg, oceans-clip-0000000089000.jpg */ List<String> cmd = new LinkedList<String>(); List<PointScreen> pointScreens = new ArrayList<>(); try { cmd.add(screenshotEXEPath); cmd.add("-i"); cmd.add(srcFileUrl); cmd.add("-scene_transition"); cmd.add("1"); cmd.add("-s"); cmd.add(size); cmd.add("-ignore-black"); cmd.add(outUrl + "\\temp\\-%013d.jpg"); ProcessBuilder pb = new ProcessBuilder(); pb.command(cmd); File tempFolder = new File(outUrl + "\\temp"); tempFolder.mkdirs(); // 开始抽帧 Process process = pb.start(); process.waitFor(); File newImageFile = null; if (tempFolder.listFiles() != null) { for (File imageFile : tempFolder.listFiles()) { String imageNameWithSuffix = imageFile.getName(); String timePoint = NanosecondsToTimeUtil .nanosecondsToTime(imageNameWithSuffix.substring(1, imageNameWithSuffix.indexOf("."))); String imageName = timePoint.replaceAll("[:|.]", "-"); newImageFile = new File(outUrl, imageName + ".jpg"); // System.out.println(newImageFile); imageFile.renameTo(newImageFile); imageFile.delete(); pointScreens.add(new PointScreen(newImageFile.getAbsolutePath(), timePoint)); } } } catch (Exception e) { logger.info("抽取关键帧报错: " + e.getMessage(), e); } return pointScreens; } public static String photoWall(String screenshotEXEPath, String srcFileUrl, String size, String outFileUrl) { shotByKeyFrame(screenshotEXEPath, srcFileUrl, size, outFileUrl); ImageAddWatermarkUtil.imageAddWatermark(outFileUrl); // ImageMergeUtil.mergeImage(outFileUrl, size); return ImageMergeUtil.mergeImage(outFileUrl, size); } public static void main(String[] args) { // System.out.println(shotByTimePoint(exePath,srcFileUrl,"00:00:00.000",size,outFileUrl));//0时间点截图测试 // shotByKeyFrame(srcFileUrl, size, outFileUrl);//0关键帧截图测试 // 1.定时截图测试 时间间隔 intervalTime 秒 // long intervalTime = 10; // long videoLength = VideoDuration.getVideoDuration(srcFileUrl); // List<PointScreen> pointScreens = new ArrayList<>(); // for (long i = 0; i <= videoLength; i = i + intervalTime) { // timePoint = // NanosecondsToTimeUtil.nanosecondsToTime(Long.toString(i*1000*10000)); // pointScreens.add(ScreenShotUtil.shotByTimePoint(srcFileUrl, timePoint, size, // outFileUrl)); // } // for (Iterator<PointScreen> iterator = pointScreens.iterator(); // iterator.hasNext();) { // System.out.println(iterator.next()); // } // 2.定点截图 // List<String> extraParam = new ArrayList<>(); // extraParam.add("00:01:01.000"); // extraParam.add("00:02:02.000"); // extraParam.add("00:03:03.000"); // extraParam.add("00:14:04.000"); // for (Iterator<String> iterator = extraParam.iterator(); iterator.hasNext();) // ScreenShotUtil.shotByTimePoint(srcFileUrl, iterator.next(), size, // outFileUrl); // 3.定量截图 // long videoDuration = VideoDuration.getVideoDuration(srcFileUrl); // int intervalTime = (int)(videoDuration/(10-1)); // for (long i = 0; i <= videoDuration; i = i + intervalTime) { // String timePoint1 = // NanosecondsToTimeUtil.nanosecondsToTime(Long.toString(i*1000*10000)); // ScreenShotUtil.shotByTimePoint(srcFileUrl, timePoint1, size, outFileUrl); // } // 4.照片墙 // System.out.println(photoWall(srcFileUrl, size, outFileUrl)); } }
获取视频时间长度:
import java.io.File; import it.sauronsoftware.jave.Encoder; import it.sauronsoftware.jave.EncoderException; import it.sauronsoftware.jave.MultimediaInfo; public class VideoDuration { public static long getVideoDuration(String srcFileUrl) { File source = new File(srcFileUrl); Encoder encoder = new Encoder(); MultimediaInfo mediaInfo = null; try { mediaInfo = encoder.getInfo(source); } catch (EncoderException e) { // TODO Auto-generated catch block e.printStackTrace(); } long duration = mediaInfo.getDuration(); return duration/1000; } public static void main(String[] args) { } }