【Java】【OpenCV】【awt】两种方式实现很「高大上」图片双重曝光

发布时间:2024年01月12日

自双重曝光产生以来,它就一直是摄影爱好者热衷于尝试的摄影手法。通过双重曝光,可以为普通的照片带来神秘的意境和让人难以言喻的感觉,使得每一个场景的纹理和颜色都有了一种如梦如幻的效果,让人沉醉于其中。

在以前,摄影师需要将两张甚至更多的底片叠加在一起,才可以实现双重曝光效果。但进入数码摄影时代之后,双重曝光的创作门槛大大降低了
————————————————
版权声明:本文为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】图片双重曝光微信小程序演示

文章来源:https://blog.csdn.net/u010651369/article/details/135553553
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。