Android

关注公众号 jb51net

关闭
首页 > 软件编程 > Android > Android图片添加水印

Android给图片添加水印的实现代码

作者:Katie。

随着社交媒体、短视频平台、电商平台、新闻门户等应用的发展,图片的使用越来越广泛,为了防止图片被非法盗用、保护版权、突出品牌标识,在图片中添加水印 成为一种常见且有效的解决方案,所以本文介绍了Android实现图片添加水印,需要的朋友可以参考下

一、项目背景详细介绍

在当前的互联网时代,图片已经成为信息传递和社交传播的重要媒介。随着社交媒体、短视频平台、电商平台、新闻门户等应用的发展,图片的使用越来越广泛。然而,图片在传播过程中极易被他人下载、二次使用甚至篡改。为了防止图片被非法盗用、保护版权、突出品牌标识,在图片中添加水印 成为一种常见且有效的解决方案。

水印的作用主要包括:

  1. 版权保护
    在图片上添加公司名称、作者署名、Logo 等水印,能够有效防止盗用,至少在传播过程中能追溯图片来源。
  2. 品牌宣传
    通过统一的品牌 Logo 作为水印,可以在每一张图片中强化品牌认知,起到宣传作用。
  3. 内容标识
    在电商、新闻平台中,水印可以用来标注“官方”、“样图”、“仅供参考”等信息,避免误导用户。
  4. 个性化展示
    用户也可能在个人图片上添加文字签名或装饰性水印,提升独特性。

因此,图片加水印在 Android 应用开发中具有极为广泛的应用场景,例如:

二、项目需求详细介绍

本项目的主要需求是 在 Android 应用中实现图片加水印功能,具体需求包括:

支持水印类型

水印位置灵活

支持透明度

操作简便

性能要求

保存与分享

三、相关技术详细介绍

要在 Android 中实现图片加水印,常用技术方案有以下几种:

使用 Canvas 绘制

使用 OpenGL 处理

使用第三方库

在本项目中,我们选用 Canvas 绘制方案,因为它简单易懂,完全依赖 Android 原生 API,不需要额外引入大型库。

四、实现思路详细介绍

我们采用以下思路来实现:

选择图片

加载图片

创建新 Bitmap

绘制原图

绘制水印

保存新图片

展示结果

五、完整实现代码

// ===================== 文件:MainActivity.java =====================
package com.example.imagewatermark;
 
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
 
import java.io.File;
import java.io.FileOutputStream;
 
/**
 * 主页面:选择图片并添加水印
 */
public class MainActivity extends AppCompatActivity {
 
    private Button btnSelectImage;
    private Button btnAddTextWatermark;
    private Button btnAddImageWatermark;
    private ImageView imageView;
 
    private Bitmap selectedBitmap;
 
    // 文件选择器
    private ActivityResultLauncher<String> imagePickerLauncher =
            registerForActivityResult(new ActivityResultContracts.GetContent(), uri -> {
                if (uri != null) {
                    try {
                        selectedBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
                        imageView.setImageBitmap(selectedBitmap);
                        Toast.makeText(this, "选择图片成功", Toast.LENGTH_SHORT).show();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
 
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        btnSelectImage = findViewById(R.id.btn_select_image);
        btnAddTextWatermark = findViewById(R.id.btn_add_text_watermark);
        btnAddImageWatermark = findViewById(R.id.btn_add_image_watermark);
        imageView = findViewById(R.id.image_view);
 
        // 选择图片
        btnSelectImage.setOnClickListener(v -> {
            imagePickerLauncher.launch("image/*");
        });
 
        // 添加文字水印
        btnAddTextWatermark.setOnClickListener(v -> {
            if (selectedBitmap == null) {
                Toast.makeText(this, "请先选择图片", Toast.LENGTH_SHORT).show();
                return;
            }
            Bitmap watermarked = WatermarkUtils.addTextWatermark(selectedBitmap, "MyWatermark", 50, 50);
            imageView.setImageBitmap(watermarked);
            saveBitmap(watermarked, "text_watermark.png");
        });
 
        // 添加图片水印
        btnAddImageWatermark.setOnClickListener(v -> {
            if (selectedBitmap == null) {
                Toast.makeText(this, "请先选择图片", Toast.LENGTH_SHORT).show();
                return;
            }
            Bitmap watermarkLogo = WatermarkUtils.decodeResource(this, R.drawable.logo);
            Bitmap watermarked = WatermarkUtils.addImageWatermark(selectedBitmap, watermarkLogo, 50, 50);
            imageView.setImageBitmap(watermarked);
            saveBitmap(watermarked, "image_watermark.png");
        });
    }
 
    /**
     * 保存 Bitmap 到本地文件
     */
    private void saveBitmap(Bitmap bitmap, String fileName) {
        try {
            File output = new File(getExternalFilesDir(null), fileName);
            FileOutputStream out = new FileOutputStream(output);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            out.flush();
            out.close();
            Toast.makeText(this, "保存成功:" + output.getAbsolutePath(), Toast.LENGTH_LONG).show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
 
 
// ===================== 文件:WatermarkUtils.java =====================
package com.example.imagewatermark;
 
import android.content.Context;
import android.graphics.*;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
 
public class WatermarkUtils {
 
    /**
     * 添加文字水印
     * @param src 原始图片
     * @param text 水印文字
     * @param x X坐标
     * @param y Y坐标
     * @return 新的带水印图片
     */
    public static Bitmap addTextWatermark(Bitmap src, String text, int x, int y) {
        Bitmap result = src.copy(Bitmap.Config.ARGB_8888, true);
        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setColor(Color.RED); // 水印颜色
        paint.setTextSize(60); // 字体大小
        paint.setAlpha(180); // 透明度
        paint.setAntiAlias(true); // 抗锯齿
        canvas.drawText(text, x, y, paint);
        return result;
    }
 
    /**
     * 添加图片水印
     * @param src 原始图片
     * @param watermark 水印图片
     * @param x X坐标
     * @param y Y坐标
     * @return 新的带水印图片
     */
    public static Bitmap addImageWatermark(Bitmap src, Bitmap watermark, int x, int y) {
        Bitmap result = src.copy(Bitmap.Config.ARGB_8888, true);
        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setAlpha(180); // 透明度
        canvas.drawBitmap(watermark, x, y, paint);
        return result;
    }
 
    /**
     * 将资源文件转换为 Bitmap
     */
    public static Bitmap decodeResource(Context context, int resId) {
        Drawable drawable = context.getResources().getDrawable(resId);
        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        }
        return null;
    }
}
 
 
// ===================== 文件:res/layout/activity_main.xml =====================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="20dp">
 
    <Button
        android:id="@+id/btn_select_image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="选择图片" />
 
    <Button
        android:id="@+id/btn_add_text_watermark"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="添加文字水印"
        android:layout_marginTop="20dp"/>
 
    <Button
        android:id="@+id/btn_add_image_watermark"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="添加图片水印"
        android:layout_marginTop="20dp"/>
 
    <ImageView
        android:id="@+id/image_view"
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:layout_marginTop="20dp"
        android:scaleType="fitCenter"/>
</LinearLayout>

六、代码详细解读

MainActivity

WatermarkUtils

activity_main.xml

七、项目详细总结

通过本项目,我们实现了一个完整的 Android 图片加水印功能,主要特点:

八、项目常见问题及解答

Q:如何设置水印在右下角?

A:只需根据原图宽高计算水印绘制的起点坐标即可,比如 x = src.getWidth() - watermark.getWidth() - 20

Q:如何设置文字旋转角度?

A:在 canvas.drawText() 前调用 canvas.rotate(angle, x, y) 即可。

Q:如何提高绘制效率?

A:避免每次都解码大图,尽量压缩后再绘制。

Q:能否实现平铺式水印?

A:可以通过循环 drawTextdrawBitmap 实现平铺效果。

Q:能否支持用户自定义字体?

A:可以使用 Typeface.createFromAsset() 设置自定义字体。

九、扩展方向与性能优化

支持平铺水印

将文字或 Logo 平铺整个图片,增加防盗效果。

支持动态参数配置

允许用户在界面上自定义水印文字、颜色、透明度、位置。

支持批量处理

一次性对多个图片批量加水印,适用于电商平台。

支持 GPU 加速

使用 OpenGL 处理大图,提高性能。

与相机结合

在拍照完成后自动加水印,而不是事后处理。

以上就是Android实现图片添加水印的示例代码的详细内容,更多关于Android图片添加水印的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文