java实现图片拼接和整合

水平拼接

横向拼接

public static void main(String[] args) {
    try {
        // 读取第一张图片
        BufferedImage image1 = ImageIO.read(new File("E:\\workspace\\images\\5.jpg"));
        // 读取第二张图片
        BufferedImage image2 = ImageIO.read(new File("E:\\workspace\\images\\4.jpg"));

        // 计算拼接后图片的宽度和高度
        int width = image1.getWidth() + image2.getWidth();
        int height = Math.max(image1.getHeight(), image2.getHeight());

        // 创建一个新的BufferedImage来存储拼接后的图片,第三个参数决定着新的图片显示的颜色
        BufferedImage concatenatedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        // 获取Graphics2D对象
        Graphics2D g2d = concatenatedImage.createGraphics();

        // 将第一张图片绘制到新的BufferedImage中
        g2d.drawImage(image1, 0, 0, null);

        // 将第二张图片绘制到新的BufferedImage中,位置在第一张图片的右边
        g2d.drawImage(image2, image1.getWidth(), 0, null);

        // 释放Graphics2D对象
        g2d.dispose();

        // 将拼接后的图片保存到文件
        ImageIO.write(concatenatedImage, "jpg", new File("E:\\workspace\\images\\test1.jpg"));

        System.out.println("图片拼接完成!");

    } catch (IOException e) {
        e.printStackTrace();
    }
}

垂直方向

// 计算拼接后图片的宽度和高度  
int width = Math.max(image1.getWidth(), image2.getWidth());  
int height = image1.getHeight() + image2.getHeight();  
  
// ...  
  
// 将第一张图片绘制到新的BufferedImage中  
g2d.drawImage(image1, 0, 0, null);  
  
// 将第二张图片绘制到新的BufferedImage中,位置在第一张图片的下方  
g2d.drawImage(image2, 0, image1.getHeight(), null);

叠加拼接

public static void main(String[] args) {
    try {
        // 加载两张图片
        BufferedImage image1 = ImageIO.read(new File("E:\\workspace\\images\\5.jpg"));
        BufferedImage image2 = ImageIO.read(new File("E:\\workspace\\images\\6.jpg"));

        // 创建一个新的BufferedImage来存储叠加后的图像
        // 假设image1足够大以容纳image2,或者你可以根据需要调整尺寸
        int width = Math.max(image1.getWidth(), image2.getWidth());
        int height = Math.max(image1.getHeight(), image2.getHeight());
        BufferedImage overlayedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

        // 获取Graphics2D对象来绘制图像
        Graphics2D g2d = overlayedImage.createGraphics();

        // 绘制第一张图片(背景)
        g2d.drawImage(image1, 0, 0, null);

        // 绘制第二张图片(叠加),这里你可以调整x和y坐标来定位image2
        // 比如,我们假设要将image2放置在image1的右下角,并且image2的左上角与image1的右下角对齐
        // 你可以根据需要调整这些值
        int x = image1.getWidth() - image2.getWidth();
        int y = image1.getHeight() - image2.getHeight();
        g2d.drawImage(image2, x, y, null);

        // 释放Graphics2D对象
        g2d.dispose();

        // 保存叠加后的图像到文件
        ImageIO.write(overlayedImage, "jpg", new File("E:\\workspace\\images\\test333.jpg"));

        System.out.println("Images have been overlayed and saved successfully.");

    } catch (IOException e) {
        e.printStackTrace();
    }
}

图片缩放

public static void main(String[] args) {
    try {
        // 加载两张图片
        BufferedImage image1 = ImageIO.read(new File("E:\\workspace\\images\\5.jpg"));
        BufferedImage newImage = resizeImage(image1, image1.getWidth() * 2, image1.getHeight() * 2);
        // 保存叠加后的图像到文件
        ImageIO.write(newImage, "jpg", new File("E:\\workspace\\images\\test222.jpg"));

        System.out.println("Images have been overlayed and saved successfully.");

    } catch (IOException e) {
        e.printStackTrace();
    }
}

// 图像缩放方法
private static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
    Image resultingImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_SMOOTH);
    BufferedImage outputImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
    Graphics2D g = outputImage.createGraphics();
    g.drawImage(resultingImage, 0, 0, null);
    g.dispose();
    return outputImage;
}

高斯模糊的图片

public static void main(String[] args) {
    try {
        // 要被模糊的图片
        BufferedImage image1 = ImageIO.read(new File("E:\\workspace\\images\\5.jpg"));

        int size = 45; // Kernel size, should be odd
        int sigma = size; //
        BufferedImage bufferedImage = applyGaussianBlur(image1, size, sigma);

        // 保存叠加后的图像到文件
        ImageIO.write(bufferedImage, "jpg", new File("E:\\workspace\\images\\test18.jpg"));

        System.out.println("Images have been overlayed and saved successfully.");

    } catch (IOException e) {
        e.printStackTrace();
    }
}

/**
 * 高斯模糊方法 虽然 size 和 sigma 是独立的参数,但选择一个合适的 size 对于给定的 sigma 是很重要的。如果 sigma 较大,但 size 较小,
 * 那么高斯核可能无法充分反映高斯函数的形状,导致模糊效果不理想
 * 通常,size 应该至少为 (2 * ceil(3 * sigma)) + 1,以确保高斯核能够覆盖到高斯函数的主要部分。这里 ceil 是向上取整的函数。这个规则是一个经验法则,用于确保核的大小足够大,以捕捉高斯函数的形状
 * 另一方面,如果 size 过大而 sigma 过小,那么核中大部分元素的值将非常接近零,这可能导致不必要的计算开销,并且不会对图像产生显著的模糊效果
 * 
 * size和sigma 相同时也可以达到数值越大越模糊的效果
 * @param size 核的维度,通常是奇数(如3x3、5x5、7x7等)
 * @param sigma 是高斯函数的标准差,它决定了模糊的程度
 * @return
 */
public static Kernel createGaussianKernel(int size, double sigma) {
    int halfSize = size / 2;
    double[] data = new double[size * size];
    double sum = 0.0;

    for (int y = -halfSize; y <= halfSize; y++) {
        for (int x = -halfSize; x <= halfSize; x++) {
            double value = (1.0 / (2.0 * Math.PI * sigma * sigma)) * Math.exp(-(x * x + y * y) / (2.0 * sigma * sigma));
            int index = (y + halfSize) * size + (x + halfSize);
            data[index] = value;
            sum += value;
        }
    }

    // Normalize the kernel so that the sum of all elements is 1
    for (int i = 0; i < data.length; i++) {
        data[i] /= sum;
    }

    // Convert double array to float array for Kernel constructor
    float[] kernelData = new float[data.length];
    for (int i = 0; i < data.length; i++) {
        kernelData[i] = (float) data[i];
    }

    return new Kernel(size, size, kernelData);
}
// 高斯模糊方法
private static BufferedImage applyGaussianBlur(BufferedImage image, int size, int sigma) {
    BufferedImageOp op = new ConvolveOp(createGaussianKernel(size, sigma), ConvolveOp.EDGE_NO_OP, null);
    return op.filter(image, null);
}

有待研究size和sigma的无关联性,即如果想着不设置边缘大小,整个图片模糊,只增加sigma值是无法达到想要的效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值