最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android給圖片添加水印的實(shí)現(xiàn)代碼

 更新時(shí)間:2025年09月02日 10:49:35   作者:Katie。  
隨著社交媒體、短視頻平臺(tái)、電商平臺(tái)、新聞門(mén)戶等應(yīng)用的發(fā)展,圖片的使用越來(lái)越廣泛,為了防止圖片被非法盜用、保護(hù)版權(quán)、突出品牌標(biāo)識(shí),在圖片中添加水印?成為一種常見(jiàn)且有效的解決方案,所以本文介紹了Android實(shí)現(xiàn)圖片添加水印,需要的朋友可以參考下

一、項(xiàng)目背景詳細(xì)介紹

在當(dāng)前的互聯(lián)網(wǎng)時(shí)代,圖片已經(jīng)成為信息傳遞和社交傳播的重要媒介。隨著社交媒體、短視頻平臺(tái)、電商平臺(tái)、新聞門(mén)戶等應(yīng)用的發(fā)展,圖片的使用越來(lái)越廣泛。然而,圖片在傳播過(guò)程中極易被他人下載、二次使用甚至篡改。為了防止圖片被非法盜用、保護(hù)版權(quán)、突出品牌標(biāo)識(shí),在圖片中添加水印 成為一種常見(jiàn)且有效的解決方案。

水印的作用主要包括:

  1. 版權(quán)保護(hù)
    在圖片上添加公司名稱、作者署名、Logo 等水印,能夠有效防止盜用,至少在傳播過(guò)程中能追溯圖片來(lái)源。
  2. 品牌宣傳
    通過(guò)統(tǒng)一的品牌 Logo 作為水印,可以在每一張圖片中強(qiáng)化品牌認(rèn)知,起到宣傳作用。
  3. 內(nèi)容標(biāo)識(shí)
    在電商、新聞平臺(tái)中,水印可以用來(lái)標(biāo)注“官方”、“樣圖”、“僅供參考”等信息,避免誤導(dǎo)用戶。
  4. 個(gè)性化展示
    用戶也可能在個(gè)人圖片上添加文字簽名或裝飾性水印,提升獨(dú)特性。

因此,圖片加水印在 Android 應(yīng)用開(kāi)發(fā)中具有極為廣泛的應(yīng)用場(chǎng)景,例如:

  • 電商平臺(tái):商品圖片加品牌 Logo。
  • 社交平臺(tái):用戶上傳圖片自動(dòng)加平臺(tái)水印。
  • 攝影類應(yīng)用:相機(jī)拍照后自動(dòng)添加簽名。
  • 教育平臺(tái):課件圖片、答題截圖加防盜用水印。

二、項(xiàng)目需求詳細(xì)介紹

本項(xiàng)目的主要需求是 在 Android 應(yīng)用中實(shí)現(xiàn)圖片加水印功能,具體需求包括:

支持水印類型

  • 文字水印:可以添加任意文字,并支持字體大小、顏色、透明度、位置設(shè)置。
  • 圖片水印:支持添加 PNG/JPG 圖片作為水印,并可調(diào)整透明度與位置。

水印位置靈活

  • 需要支持常見(jiàn)的四個(gè)位置:左上角、右上角、左下角、右下角。
  • 允許設(shè)置偏移量(x/y 偏移)。

支持透明度

  • 無(wú)論文字水印還是圖片水印,都要能控制透明度。

操作簡(jiǎn)便

  • 提供簡(jiǎn)單的 UI,用戶可選擇原圖,點(diǎn)擊按鈕即可生成帶水印的圖片。

性能要求

  • 添加水印操作需在子線程中完成,避免主線程卡頓。
  • 輸出圖片需保持較高清晰度,避免嚴(yán)重失真。

保存與分享

  • 加水印后的圖片需要保存到本地存儲(chǔ)中,方便用戶再次使用或分享。

三、相關(guān)技術(shù)詳細(xì)介紹

要在 Android 中實(shí)現(xiàn)圖片加水印,常用技術(shù)方案有以下幾種:

使用 Canvas 繪制

  • Android 提供 Canvas 類,可以對(duì) Bitmap 進(jìn)行繪制。
  • 實(shí)現(xiàn)方式:先將原圖繪制到 Canvas 上,再在其上繪制文字或水印圖片。
  • 優(yōu)點(diǎn):簡(jiǎn)單高效,依賴 Android 原生 API。
  • 缺點(diǎn):適合靜態(tài)圖片,不支持復(fù)雜濾鏡。

使用 OpenGL 處理

  • 通過(guò) OpenGL 渲染圖片,然后疊加水印紋理。
  • 優(yōu)點(diǎn):適合批量處理和大圖,性能高。
  • 缺點(diǎn):實(shí)現(xiàn)復(fù)雜,不適合入門(mén)。

使用第三方庫(kù)

  • GlidePicasso 主要做圖片加載,本身不提供水印功能。
  • 可以使用一些專門(mén)的圖片處理庫(kù),但多數(shù)仍然基于 Canvas 或 OpenGL。

在本項(xiàng)目中,我們選用 Canvas 繪制方案,因?yàn)樗?jiǎn)單易懂,完全依賴 Android 原生 API,不需要額外引入大型庫(kù)。

四、實(shí)現(xiàn)思路詳細(xì)介紹

我們采用以下思路來(lái)實(shí)現(xiàn):

選擇圖片

  • 使用 Android 系統(tǒng)文件選擇器,用戶從相冊(cè)中選擇圖片。

加載圖片

  • 將選擇的圖片轉(zhuǎn)換為 Bitmap,用于后續(xù)繪制。

創(chuàng)建新 Bitmap

  • 新建一個(gè)與原圖相同大小的 Bitmap,并在其上創(chuàng)建 Canvas。

繪制原圖

  • 在 Canvas 上先繪制原始圖片。

繪制水印

  • 如果是文字水?。菏褂?Paint.setTextSizesetColor、setAlpha 設(shè)置樣式后繪制文字。
  • 如果是圖片水?。杭虞d水印圖片 Bitmap,使用 canvas.drawBitmap() 繪制在指定位置。

保存新圖片

  • 將合成的 Bitmap 保存到本地文件。

展示結(jié)果

  • 在 ImageView 中展示帶水印的新圖片。

五、完整實(shí)現(xiàn)代碼

// ===================== 文件: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;
 
/**
 * 主頁(yè)面:選擇圖片并添加水印
 */
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, "請(qǐng)先選擇圖片", 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, "請(qǐng)先選擇圖片", 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坐標(biāo)
     * @param y Y坐標(biāo)
     * @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坐標(biāo)
     * @param y Y坐標(biāo)
     * @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;
    }
 
    /**
     * 將資源文件轉(zhuǎn)換為 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>

六、代碼詳細(xì)解讀

MainActivity

  • 負(fù)責(zé) UI 邏輯,包括選擇圖片、調(diào)用水印工具類生成新圖片,并保存到本地。

WatermarkUtils

  • addTextWatermark():在原圖上繪制文字水印,支持位置、字體大小、透明度。
  • addImageWatermark():在原圖上繪制一張 PNG 圖片作為水印。
  • decodeResource():將資源文件的圖片轉(zhuǎn)換為 Bitmap,用作水印素材。

activity_main.xml

  • 包含三個(gè)按鈕和一個(gè) ImageView,分別用于選擇圖片、添加文字水印、添加圖片水印,并顯示結(jié)果。

七、項(xiàng)目詳細(xì)總結(jié)

通過(guò)本項(xiàng)目,我們實(shí)現(xiàn)了一個(gè)完整的 Android 圖片加水印功能,主要特點(diǎn):

  • 使用原生 API(Canvas + Paint),實(shí)現(xiàn)簡(jiǎn)單、依賴少。
  • 支持 文字水印圖片水印。
  • 支持設(shè)置透明度、位置,滿足大多數(shù)場(chǎng)景需求。
  • 圖片最終保存到本地,方便后續(xù)分享或使用。

八、項(xiàng)目常見(jiàn)問(wèn)題及解答

Q:如何設(shè)置水印在右下角?

A:只需根據(jù)原圖寬高計(jì)算水印繪制的起點(diǎn)坐標(biāo)即可,比如 x = src.getWidth() - watermark.getWidth() - 20。

Q:如何設(shè)置文字旋轉(zhuǎn)角度?

A:在 canvas.drawText() 前調(diào)用 canvas.rotate(angle, x, y) 即可。

Q:如何提高繪制效率?

A:避免每次都解碼大圖,盡量壓縮后再繪制。

Q:能否實(shí)現(xiàn)平鋪式水?。?/strong>

A:可以通過(guò)循環(huán) drawTextdrawBitmap 實(shí)現(xiàn)平鋪效果。

Q:能否支持用戶自定義字體?

A:可以使用 Typeface.createFromAsset() 設(shè)置自定義字體。

九、擴(kuò)展方向與性能優(yōu)化

支持平鋪水印

將文字或 Logo 平鋪整個(gè)圖片,增加防盜效果。

支持動(dòng)態(tài)參數(shù)配置

允許用戶在界面上自定義水印文字、顏色、透明度、位置。

支持批量處理

一次性對(duì)多個(gè)圖片批量加水印,適用于電商平臺(tái)。

支持 GPU 加速

使用 OpenGL 處理大圖,提高性能。

與相機(jī)結(jié)合

在拍照完成后自動(dòng)加水印,而不是事后處理。

以上就是Android實(shí)現(xiàn)圖片添加水印的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Android圖片添加水印的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

虹口区| 漳浦县| 通城县| 通榆县| 林西县| 秦皇岛市| 黄大仙区| 绵阳市| 凯里市| 垣曲县| 资中县| 河东区| 商丘市| 个旧市| 盐城市| 武汉市| 泸州市| 吉木萨尔县| 东港市| 太湖县| 甘洛县| 两当县| 卢龙县| 饶河县| 双鸭山市| 延寿县| 尚志市| 讷河市| 武安市| 印江| 澎湖县| 红桥区| 芦山县| 齐河县| 秦皇岛市| 汉阴县| 阳信县| 区。| 确山县| 杂多县| 保康县|