自双重曝光产生以来,它就一直是摄影爱好者热衷于尝试的摄影手法。通过双重曝光,可以为普通的照片带来神秘的意境和让人难以言喻的感觉,使得每一个场景的纹理和颜色都有了一种如梦如幻的效果,让人沉醉于其中。
在以前,摄影师需要将两张甚至更多的底片叠加在一起,才可以实现双重曝光效果。但进入数码摄影时代之后,双重曝光的创作门槛大大降低了
————————————————
版权声明:本文为CSDN博主「鹤田裕志」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42382703/article/details/114958728
左侧两张为原图 右侧为 效果图
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;
}
}
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】图片双重曝光微信小程序演示