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

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

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

一、項目背景詳細介紹

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

水印的作用主要包括:

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

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

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

二、項目需求詳細介紹

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

支持水印類型

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

水印位置靈活

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

支持透明度

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

操作簡便

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

性能要求

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

保存與分享

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

三、相關技術詳細介紹

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

使用 Canvas 繪制

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

使用 OpenGL 處理

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

使用第三方庫

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

在本項目中,我們選用 Canvas 繪制方案,因為它簡單易懂,完全依賴 Android 原生 API,不需要額外引入大型庫。

四、實現(xiàn)思路詳細介紹

我們采用以下思路來實現(xiàn):

選擇圖片

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

加載圖片

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

創(chuàng)建新 Bitmap

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

繪制原圖

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

繪制水印

  • 如果是文字水?。菏褂?Paint.setTextSize、setColorsetAlpha 設置樣式后繪制文字。
  • 如果是圖片水印:加載水印圖片 Bitmap,使用 canvas.drawBitmap() 繪制在指定位置。

保存新圖片

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

展示結(jié)果

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

五、完整實現(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;
 
/**
 * 主頁面:選擇圖片并添加水印
 */
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;
    }
 
    /**
     * 將資源文件轉(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>

六、代碼詳細解讀

MainActivity

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

WatermarkUtils

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

activity_main.xml

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

七、項目詳細總結(jié)

通過本項目,我們實現(xiàn)了一個完整的 Android 圖片加水印功能,主要特點:

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

八、項目常見問題及解答

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

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

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

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

Q:如何提高繪制效率?

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

Q:能否實現(xiàn)平鋪式水???

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

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

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

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

支持平鋪水印

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

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

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

支持批量處理

一次性對多個圖片批量加水印,適用于電商平臺。

支持 GPU 加速

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

與相機結(jié)合

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

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

相關文章

最新評論

深水埗区| 镇原县| 襄垣县| 胶南市| 垣曲县| 安平县| 汝南县| 建昌县| 新龙县| 崇明县| 察哈| 彩票| 武宣县| 西林县| 叶城县| 务川| 宁远县| 开化县| 安宁市| 霍山县| 宽甸| 武乡县| 休宁县| 通山县| 大足县| 怀柔区| 灵石县| 寻甸| 北宁市| 滦平县| 阜宁县| 邯郸市| 峨边| 桂平市| 西平县| 高邑县| 县级市| 麦盖提县| 比如县| 临洮县| 河东区|