如何在Android中为图像添加水印效果?

22

我有一张包含帧的图片,需要加上水印效果。应该如何实现?

8个回答

41

我在这里找到了一篇关于Android图片处理的优秀教程

public static Bitmap mark(Bitmap src, String watermark, Point location, Color color, int alpha, int size, boolean underline) {
    int w = src.getWidth();
    int h = src.getHeight();
    Bitmap result = Bitmap.createBitmap(w, h, src.getConfig());

    Canvas canvas = new Canvas(result);
    canvas.drawBitmap(src, 0, 0, null);

    Paint paint = new Paint();
    paint.setColor(color);
    paint.setAlpha(alpha);
    paint.setTextSize(size);
    paint.setAntiAlias(true);
    paint.setUnderlineText(underline);
    canvas.drawText(watermark, location.x, location.y, paint);

    return result;
}

感谢 Pete Houston 分享如此有用的基本图像处理教程。


我可以在另一个指定了图像的函数中调用这个方法吗? - info
1
你可以在另一个函数中调用它。例如 - Bitmap result = mark(src, watermark, location, color, alpha, size, underline); - AndroidLearner
1
参数Color color应该是int color,方法paint.setColor()正在等待int类型的参数。如果您有更好的想法,请与我们分享。 - technik
嗨,它没起作用。我在一个片段内使用它在一个图像视图上。 - Faris Muhammed
在我捕获图像后,我将其转换为位图并将其保存在存储中。因此,在保存之前,当我使用上述代码在该位图图像上写水印时,它无法正常工作。您能否提供更多细节? - user14016776

20

供他人参考,如果你想在图片顶部添加你的应用程序标志(该标志位于drawable文件夹中),请使用以下方法:

private Bitmap addWaterMark(Bitmap src) {
        int w = src.getWidth();
        int h = src.getHeight();
        Bitmap result = Bitmap.createBitmap(w, h, src.getConfig());
        Canvas canvas = new Canvas(result);
        canvas.drawBitmap(src, 0, 0, null);

        Bitmap waterMark = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.logo);
        canvas.drawBitmap(waterMark, 0, 0, null);

        return result;
    }

1
我从水印位图中得到了null,这是为什么? - Andrey Solera
1
我在图片上什么都没有得到。它只是保存而没有水印。有什么帮助吗! - user14016776
评论没有得到回复,怎么回事?你们还好吗?我也无法看到图片上方的任何内容。 - Maseed

14
如果有人仍在寻找此功能,我在这里找到了一个好的解决方案:这里。它会向图像的右下角添加水印,并根据源图像进行缩放,这正是我所需要的。
/**
 * Embeds an image watermark over a source image to produce
 * a watermarked one.
 * @param source The source image where watermark should be placed
 * @param watermark Watermark image to place
 * @param ratio A float value < 1 to give the ratio of watermark's height to image's height,
 *             try changing this from 0.20 to 0.60 to obtain right results
 */
public static Bitmap addWatermark(Bitmap source, Bitmap watermark, float ratio) {
    Canvas canvas;
    Paint paint;
    Bitmap bmp;
    Matrix matrix;
    RectF r;

    int width, height;
    float scale;

    width = source.getWidth();
    height = source.getHeight();

    // Create the new bitmap
    bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);

    // Copy the original bitmap into the new one
    canvas = new Canvas(bmp);
    canvas.drawBitmap(source, 0, 0, paint);

    // Scale the watermark to be approximately to the ratio given of the source image height
    scale = (float) (((float) height * ratio) / (float) watermark.getHeight());

    // Create the matrix
    matrix = new Matrix();
    matrix.postScale(scale, scale);

    // Determine the post-scaled size of the watermark
    r = new RectF(0, 0, watermark.getWidth(), watermark.getHeight());
    matrix.mapRect(r);

    // Move the watermark to the bottom right corner
    matrix.postTranslate(width - r.width(), height - r.height());

    // Draw the watermark
    canvas.drawBitmap(watermark, matrix, paint);

    return bmp;
}

而且它有很好的注释,这是一个巨大的优点!


1
干得好,@Irshad。 - Biraj Zalavadia
对我来说完美运行。 - Lefty

4

看起来您正在寻找一个类似于waterrippleeffect的东西。请查看完整的源代码。同时,查看截图以了解效果。


1
在Kotlin中:
注意:这只是上面答案的修改代码。
private fun mark(src: Bitmap, watermark: String): Bitmap {
        val w = src.width
        val h = src.height
        val result = Bitmap.createBitmap(w, h, src.config)
        val canvas = Canvas(result)
        canvas.drawBitmap(src, 0f, 0f, null)
        val paint = Paint()
        paint.color = Color.RED
        paint.textSize = 10f
        paint.isAntiAlias = true
        paint.isUnderlineText = true
        canvas.drawText(watermark, 20f, 25f, paint)
        return result
    }

val imageBitmap = mark(yourBitmap, "Your Text")
binding.meetProofImageView.setImageBitmap(imageBitmap)

0

我尝试了一些在其他帖子中提到的库,比如this,但不幸的是它已经失踪了,现在也无法下载。所以我遵循了AndroidLearner 's answer的建议,但稍微调整了一下代码,对于那些在旋转水印时遇到困难以及Paint类各种方法的有效值是什么,以便文本显示成角度旋转(就像大多数公司水印一样),您可以使用以下代码。
请注意,wh分别是屏幕的宽度和高度,您可以轻松计算,有很多方法可以在stackoverflow上找到。

public static Bitmap waterMarkBitmap(Bitmap src, String watermark) {
    int w = src.getWidth();
    int h = src.getHeight();
    Bitmap mutableBitmap = Utils.getMutableBitmap(src);
    Bitmap result = Bitmap.createBitmap(w, h, mutableBitmap.getConfig());

    Canvas canvas = new Canvas(result);
    canvas.drawBitmap(src, 0f, 0f, null);

    Paint paint = new Paint();
    paint.setColor(Color.RED);
    paint.setTextSize(92f);
    paint.setAntiAlias(true);
    paint.setAlpha(70);  // accepts value between 0 to 255, 0 means 100% transparent, 255 means 100% opaque.
    paint.setUnderlineText(false);
    canvas.rotate(45, w / 10f, h / 4f);
    canvas.drawText(watermark, w / 10f, h / 4f, paint);
    canvas.rotate(-45, w / 10f, h / 4f);

    return result;
}

它将文本水印旋转45度,并将其放置在位图的中心。

还要注意,如果您无法获取水印,则可能是您使用的源位图是不可变的情况。对于这种最坏的情况,您可以使用下面的方法从不可变的位图创建可变位图。

public static Bitmap getMutableBitmap(Bitmap immutableBitmap) {
    if (immutableBitmap.isMutable()) {
        return immutableBitmap;
    }

    Bitmap workingBitmap = Bitmap.createBitmap(immutableBitmap);
    return workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
}

我在这里找到了上述方法。我已经在我的应用程序中使用了这两种方法进行测试,在添加了上述调整后,它完美地运行。请尝试并告诉我是否有效。


0

您可以使用androidWM将水印添加到您的图像中,甚至可以添加不可见的水印:

添加依赖项:

dependencies {
  ...
  implementation 'com.huangyz0918:androidwm:0.2.3'
  ...
}

以及Java代码:

 WatermarkText watermarkText = new WatermarkText(“Hello World”)
                    .setPositionX(0.5) 
                    .setPositionY(0.5) 
                    .setTextAlpha(100) 
                    .setTextColor(Color.WHITE) 
                    .setTextFont(R.font.champagne) 
                    .setTextShadow(0.1f, 5, 5, Color.BLUE); 

 WatermarkBuilder.create(this, backgroundBitmap) 
                    .loadWatermarkText(watermarkText) 
                    .getWatermark() 
                    .setToImageView(backgroundView); 


您可以轻松地添加图像类型的水印或文本水印,而且该库的大小小于30Kb。

不要将工具链接作为答案发布,特别是如果您编写了该工具,则需要披露关联性,否则就是垃圾邮件。 - Jean-François Fabre

-5
使用FrameLayout。将两个ImageView放置在FrameLayout中,并指定水印ImageView的位置。

水印意味着第二张图片将成为第一张图片的一部分,然后可以像共享带有水印的第一张图片一样使用。Framelayout只是展示两张图片,但不会改变它们。 - صلي علي محمد - Atef Farouk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接