desc:java代码方式添加水印

main
xiaowusky 2 years ago
parent dc57e3f0ab
commit 73004fe84d

@ -404,6 +404,9 @@ public class MediaStream extends Service implements LifecycleObserver {
public void onPreviewFrame2(byte[] data, Object camera) {
if (camera instanceof Camera) {
if (PreferenceManager.getDefaultSharedPreferences(mApplicationContext).getBoolean("key_enable_video_overlay", true)) {
overlay.javaOverlay(data, "EasyPusher");
}
if (mDgree == 0) {
Camera.CameraInfo camInfo = new Camera.CameraInfo();
Camera.getCameraInfo(mCameraId, camInfo);
@ -425,6 +428,7 @@ public class MediaStream extends Service implements LifecycleObserver {
if (PreferenceManager.getDefaultSharedPreferences(mApplicationContext).getBoolean("key_enable_video_overlay", true)) {
String txt;// = String.format("drawtext=fontfile=" + mApplicationContext.getFileStreamPath("SIMYOU.ttf") + ": text='%s%s':x=(w-text_w)/2:y=H-60 :fontcolor=white :box=1:boxcolor=0x00000000@0.3", "EasyPusher", new SimpleDateFormat("yyyy-MM-ddHHmmss").format(new Date()));
txt = "EasyPusher " + new SimpleDateFormat("yy-MM-dd HH:mm:ss SSS").format(new Date());
overlay.javaOverlay(data, txt);
overlay.overlay(data, txt);
}
mVC.onVideo(data, NV21);

@ -1,8 +1,13 @@
package org.easydarwin.sw;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
import org.easydarwin.easypusher.R;
import org.easydarwin.util.YUVUtils;
import java.io.File;
/**
@ -17,32 +22,54 @@ public class TxtOverlay {
private final Context context;
public TxtOverlay(Context context){
int startY = 100;//水印Y轴的位置
int startX = 100;//水印X轴的位置
Bitmap bmp;
byte[] mark;
public TxtOverlay(Context context) {
this.context = context;
//从drawble中获取水印图片
Bitmap bmp1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.float_button);
//缩小图片
bmp = YUVUtils.scaleImage(bmp1, 40, 40);
//转YUV
mark = YUVUtils.getYUVByBitmap(bmp);
}
private long ctx;
public void init(int width, int height,String fonts) {
if (TextUtils.isEmpty(fonts)){
public void init(int width, int height, String fonts) {
if (TextUtils.isEmpty(fonts)) {
throw new IllegalArgumentException("the font file must be valid!");
}
if (!new File(fonts).exists()){
if (!new File(fonts).exists()) {
throw new IllegalArgumentException("the font file must be exists!");
}
ctx = txtOverlayInit(width, height,fonts);
ctx = txtOverlayInit(width, height, fonts);
}
public void overlay(byte[] data,
String txt) {
// txt = "drawtext=fontfile="+context.getFileStreamPath("SIMYOU.ttf")+": text='EasyPusher 2017':x=(w-text_w)/2:y=H-60 :fontcolor=white :box=1:boxcolor=0x00000000@0.3";
// txt = "movie=/sdcard/qrcode.png [logo];[in][logo] "
// + "overlay=" + 0 + ":" + 0
// + " [out]";
// if (ctx == 0) throw new RuntimeException("init should be called at first!");
if (ctx == 0) return;
txtOverlay(ctx, data, txt);
}
public void javaOverlay(byte[] data,
String txt) {
if (ctx == 0) return;
int j = 0;
for (int i = startY; i < bmp.getHeight() + startY; i++) {
for (int c = 0; c < bmp.getWidth(); c++) {
//去掉PNG水印的黑边
if (mark[j * bmp.getWidth() + c] != 0x10 && mark[j * bmp.getWidth() + c] != 0x80 && mark[j * bmp.getWidth() + c] != 0xeb) {
System.arraycopy(mark, j * bmp.getWidth() + c, data, startX + i * 1280 + c, 1);
}
}
j++;
}
}
public void release() {
if (ctx == 0) return;
txtOverlayRelease(ctx);

@ -0,0 +1,73 @@
package org.easydarwin.util;
import android.graphics.Bitmap;
import android.graphics.Matrix;
public class YUVUtils {
//缩小图片到制定长宽
public static Bitmap scaleImage(Bitmap bm, int newWidth, int newHeight) {
if (bm == null) {
return null;
}
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix,
true);
if (bm != null & !bm.isRecycled()) {
bm.recycle();
bm = null;
}
return newbm;
}
//图片转YUV
public static byte[] getYUVByBitmap(Bitmap bitmap) {
if (bitmap == null) {
return null;
}
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int size = width * height;
int pixels[] = new int[size];
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
byte[] data = rgb2YCbCr420(pixels, width, height);
return data;
}
public static byte[] rgb2YCbCr420(int[] pixels, int width, int height) {
int len = width * height;
//yuv格式数组大小y亮度占len长度u,v各占len/4长度。
byte[] yuv = new byte[len * 3 / 2];
int y, u, v;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
//屏蔽ARGB的透明度值
int rgb = pixels[i * width + j] & 0x00FFFFFF;
//像素的颜色顺序为bgr移位运算。
int r = rgb & 0xFF;
int g = (rgb >> 8) & 0xFF;
int b = (rgb >> 16) & 0xFF;
//套用公式
y = ((66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
u = ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
v = ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
y = y < 16 ? 16 : (y > 255 ? 255 : y);
u = u < 0 ? 0 : (u > 255 ? 255 : u);
v = v < 0 ? 0 : (v > 255 ? 255 : v);
//赋值
yuv[i * width + j] = (byte) y;
yuv[len + (i >> 1) * width + (j & ~1) + 0] = (byte) u;
yuv[len + +(i >> 1) * width + (j & ~1) + 1] = (byte) v;
}
}
return yuv;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Loading…
Cancel
Save