自双重曝光产生以来,它就一直是摄影爱好者热衷于尝试的摄影手法。通过双重曝光,可以为普通的照片带来神秘的意境和让人难以言喻的感觉,使得每一个场景的纹理和颜色都有了一种如梦如幻的效果,让人沉醉于其中。
在以前,摄影师需要将两张甚至更多的底片叠加在一起,才可以实现双重曝光效果。但进入数码摄影时代之后,双重曝光的创作门槛大大降低了
————————————————
版权声明:本文为CSDN博主「鹤田裕志」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42382703/article/details/114958728
原图以及效果图
左侧两张为原图 右侧为 效果图
awt实现双重曝光
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;/*** @author 小帅丶* @Description Java模拟双重曝光对图片进行处理* 图片双重曝光Java实现* 两张图片一定要宽高一致* @date 2024/1/10*/
public class DoubleExposureUtil {//默认透明度private static float alpha = 0.5f;/*** @Description 模拟双重曝光* @param firstPath - 第一张图片* @param secondPath - 第二张图片* @Date 2024/1/10* @Author 小帅丶* @return java.awt.image.BufferedImage**/public static BufferedImage doubleExposure(String firstPath, String secondPath) throws Exception {return doubleExposure(firstPath,secondPath,alpha);}/*** @Description 模拟双重曝光* @param firstPath - 第一张图片* @param secondPath - 第二张图片* @param alpha - 透明度* @Date 2024/1/10* @Author 小帅丶* @return java.awt.image.BufferedImage**/public static BufferedImage doubleExposure(String firstPath, String secondPath, float alpha) throws Exception {return doubleExposure(firstPath,secondPath,alpha,alpha);}/*** @Description 模拟双重曝光* @param firstPath - 第一张图片* @param secondPath - 第二张图片* @param firstAlpha - 第一张图透明度* @param secondAlpha - 第二张图透明度* @Date 2024/1/10* @Author 小帅丶* @return java.awt.image.BufferedImage**/public static BufferedImage doubleExposure(String firstPath, String secondPath,float firstAlpha, float secondAlpha) throws Exception {// 读取第一张图片BufferedImage image1 = ImageIO.read(new File(firstPath));// 读取第二张图片BufferedImage image2 = ImageIO.read(new File(secondPath));if (image1.getWidth() == image2.getWidth() && image1.getHeight() == image2.getHeight()) {// 将两张图片合并成一张BufferedImage combinedImage = new BufferedImage(image1.getWidth(), image1.getHeight(),BufferedImage.TYPE_INT_ARGB);Graphics2D g2d = combinedImage.createGraphics();g2d.drawImage(image1, 0, 0, null);g2d.setComposite(AlphaComposite.SrcOver.derive(firstAlpha));g2d.drawImage(image2, 0, 0, null);g2d.setComposite(AlphaComposite.SrcOver.derive(secondAlpha));g2d.dispose();// 实现双重曝光效果BufferedImage doubleExposureImage = new BufferedImage(image1.getWidth(), image1.getHeight(),BufferedImage.TYPE_INT_ARGB);Graphics2D g2dExposure = doubleExposureImage.createGraphics();g2dExposure.drawImage(combinedImage, 0, 0, null);g2dExposure.dispose();return doubleExposureImage;}return null;}
}
OpenCV实现双重曝光
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;import java.awt.*;
import java.awt.image.BufferedImage;/*** @author 小帅丶* @Description OpenCV 双重曝光* @date 2024/1/12 14:15:54*/
public class TianDiTuSample {/*** @Description 模拟双重曝光-需要引入javacv-platform* @param openCVdllPath - opencvdll文件路径* @param firstPath - 第一张图片* @param secondPath - 第二张图片* @param firstAlpha - 第一张图透明度* @param secondAlpha - 第二张图透明度* @return java.awt.image.BufferedImage* <dependency>* <groupId>org.bytedeco</groupId>* <artifactId>javacv-platform</artifactId>* <version>1.5.7</version>* </dependency>* @Date 2024/1/10* @Author 小帅丶**/public static BufferedImage doubleExposureByOpenCV(String openCVdllPath,String firstPath, String secondPath,float firstAlpha, float secondAlpha) throws Exception {//加载dll文件System.load(openCVdllPath);// 加载本地图像文件Mat image1 = Imgcodecs.imread(firstPath);Mat image2 = Imgcodecs.imread(secondPath);if (image1.empty() || image2.empty()) {System.out.println("无法读取图像文件!");return null;}// 创建输出结果图像对象Mat resultImage = new Mat();// 将两张图像进行相加操作Core.addWeighted(image1, firstAlpha, image2, secondAlpha, 0, resultImage);// 保存结果图像到本地Imgcodecs.imwrite("result_image.jpg", resultImage);//Mat转BufferedImage bufferedImage保存最好是png格式 未深究 如果保存jpg会变红BufferedImage bufferedImage = matToBufferedImage(resultImage);// 释放内存image1.release();image2.release();resultImage.release();return bufferedImage;}/*** @param mat - Mat对象* @return java.awt.image.BufferedImage* @Description Mat转BufferedImage* @Author 小帅丶* @Date 2024/1/12**/public static BufferedImage matToBufferedImage(Mat mat) {// 获取图像的宽度和高度int width = mat.cols();int height = mat.rows();// 创建一个空的BufferedImage,具有与Mat相同的宽度和高度,以及与Mat相同的深度和类型BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);// 将Mat的像素数据复制到BufferedImage中for (int y = 0; y < height; y++) {for (int x = 0; x < width; x++) {// 假设图像是灰度图,获取像素值(如果是彩色图,需要相应地修改)// int pixel = (int)mat.get(y, x)[0];int b = (int) mat.get(y, x)[0];int g = (int) mat.get(y, x)[1];int r = (int) mat.get(y, x)[2];// 将像素值设置为颜色值bufferedImage.setRGB(x, y, new Color(r, g, b).getRGB());}}return bufferedImage;}
}
小程序功能演示
可以搜索 小帅一点资讯 在微信小程序直接体验哦
【Java】图片双重曝光微信小程序演示