Coder Social home page Coder Social logo

huangyz0918 / androidwm Goto Github PK

View Code? Open in Web Editor NEW
1.6K 23.0 197.0 4.01 MB

An android image watermark library that supports steganography.

Home Page: http://huangyz.name/AndroidWM/

License: Apache License 2.0

Java 91.45% CMake 1.57% C++ 6.98%
image-processing watermark android-library encryption watermarking watermark-image

androidwm's Introduction

AndroidWM

Codacy BadgeFOSSA Status wiki

A lightweight android image watermark library that supports encrypted watermarks. 中文版本

Download Library

Gradle:

For androidWM supports the invisible digital watermarks (package size: 1Mb):

implementation 'com.huangyz0918:androidwm:0.2.3'

For androidWM-light only supports the visible watermarks (package size: 28Kb):

implementation 'com.huangyz0918:androidwm-light:0.1.2'

Quick Start

Build a Watermark

After downloading the library and adding it into your project, You can create a WatermarkImage or WatermarkText and do some pre-settings with their instance.

    WatermarkText watermarkText = new WatermarkText(inputText)
            .setPositionX(0.5)
            .setPositionY(0.5)
            .setOrigin(new WatermarkPosition(0.5, 0.5))
            .setTextColor(Color.WHITE)
            .setTextFont(R.font.champagne)
            .setTextShadow(0.1f, 5, 5, Color.BLUE)
            .setTextAlpha(150)
            .setRotation(30)
            .setTextSize(20);

There are many attributes that can help you to make a customization with a text watermark or an image watermark. You can get more information from the documentation section that follows.

After the preparation is complete, you need a WatermarkBuilder to create a watermark image. You can get an instance from the create method of WatermarkBuilder, and, you need to put a Bitmap or an int Drawable as the background image first.

    WatermarkBuilder
            .create(context, backgroundBitmap)
            .loadWatermarkText(watermarkText) // use .loadWatermarkImage(watermarkImage) to load an image.
            .getWatermark()
            .setToImageView(imageView);

Select the Drawing Mode

You can select normal mode (default) or tile mode in WatermarkBuilder.setTileMode():

    WatermarkBuilder
            .create(this, backgroundBitmap)
            .loadWatermarkText(watermarkText)
            .setTileMode(true) // select different drawing mode.
            .getWatermark()
            .setToImageView(backgroundView);

Boom! the watermark has been drawed now:

Get the Output

You can create both text watermark and image watermark, and load them into your WatermarkBuilder. If you want to get the result bitmap, we also have a .getOutputImage() method for you after getting the watermark:

    Bitmap bitmap = WatermarkBuilder
            .create(this, backgroundBitmap)
            .getWatermark()
            .getOutputImage();

Build Multiple Watermarks

And if you want to add many watermarks at the same time, you can use a List<> to hold your watermarks. You can add the List<> into the background image by .loadWatermarkTexts(watermarkTexts), the same as watermark images:

    WatermarkBuilder
            .create(this, backgroundBitmap)
            .loadWatermarkTexts(watermarkTexts)
            .loadWatermarkImages(watermarkImages)
            .getWatermark();

Ways of Loading Resources

If you want to load a watermark image or a watermark text from a view or resources, you can use those methods:

WatermarkText watermarkText = new WatermarkText(editText); // for a text from EditText.
WatermarkText watermarkText = new WatermarkText(textView); // for a text from TextView.
WatermarkImage watermarkImage = new WatermarkImage(imageView); // for an image from ImageView.
WatermarkImage watermarkImage = new WatermarkImage(this, R.drawable.image); // for an image from Resource.

The background loaded in WatermarkBuilder can be created from resources or ImageView too:

    WatermarkBuilder
            .create(this, backgroundImageView) // .create(this, R.drawable.background)
            .getWatermark()

If you didn't load a watermark ,the default value is as the same as background, nothing will be changed.

Invisible Watermarks (beta)

In this library, we also support the invisible watermark and the detection of them. We can use two ways to build an invisible watermark: the LSB (spatial domain) and the wavelet transform (Frequency domain). All you need to do is to use a boolean (isLSB) to distinguish them. (PS. the watermark in frequency domain is under developing)

You can create a new invisible watermark by the WatermarkBuilder's .setInvisibleWMListener:

     WatermarkBuilder
            .create(this, backgroundBitmap)
            .loadWatermarkImage(watermarkBitmap)
            .setInvisibleWMListener(true, new BuildFinishListener<Bitmap>() {
                @Override
                public void onSuccess(Bitmap object) {
                    if (object != null) {
                       // do something...
                    }
                }

                @Override
                public void onFailure(String message) {
                      // do something...
                }
            });

The first paramter of setInvisibleWMListener is isLSB, if false, the invisible algorithm will change to the frequency domain.

To detect the invisible watermark, you can use WatermarkDetector, you need to put a boolean parameter in .create method, since we have two kinds of invisible watermarks, if isLSB is true, the detector can detect LSB watermarks, if not, the detector can detect the watermarks in the frequency domain.

     WatermarkDetector
            .create(inputBitmap, true)
            .detect(false, new DetectFinishListener() {
                @Override
                public void onSuccess(DetectionReturnValue returnValue) {
                       Bitmap watermarkImage = returnValue.getWatermarkBitmap();
                       String watermarkString = returnValue.getWatermarkString();
                 }

                @Override
                public void onFailure(String message) {
                       // do something...
                }
            });

Here are the Demos for Least Significant Bits (LSB) invisible watermark:

Invisible Text (LSB) Invisible Image (LSB)

For more information, please checkout Wiki, enjoy yourself! 😘

License

   Copyright 2018 Yizheng Huang

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

androidwm's People

Contributors

codacy-badger avatar cubicpill avatar huangyz0918 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

androidwm's Issues

只要使用隐形水印就会崩溃

日志如下:
Caused by: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/com.xiachufang-BzBASljGJfTQVm4wk-NAIA==/base.apk"],nativeLibraryDirectories=[/data/app/com.xiachufang-BzBASljGJfTQVm4wk-NAIA==/lib/arm, /data/app/com.xiachufang-BzBASljGJfTQVm4wk-NAIA==/base.apk!/lib/armeabi, /system/lib, /product/lib]]] couldn't find "libWatermark.so"

隐藏图报错

A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xc7980000 in tid 23057 (AsyncTask #1), pid 21895 (scenery.toolbox)

为什么第一进入界面不显示水印

为什么第一进入界面不显示水印,第二次才显示出来?
WatermarkText watermarkText = new WatermarkText(text)
.setPositionX(0.5)
.setPositionY(0.5)
.setTextAlpha(80)
.setTextColor(getResources().getColor(R.color.color_FFFFFF))
// .setTextFont(R.font.champagne)
.setTextShadow(0.1f, 5, 5, getResources().getColor(R.color.color_5052c3));

    WatermarkBuilder.create(getContext(), mImgBottom)
            .setTileMode(true)
            .loadWatermarkText(watermarkText)
            .getWatermark()
            .setToImageView(mImgBottom);

Does it strange for that set image size to 1024??

If I have image that width and height is both < 1024. This lib create the bitmap set one to 1024.

    private WatermarkBuilder(@NonNull Context context, @NonNull Bitmap backgroundImg) {
        this.context = context;
        this.backgroundImg = resizeBitmap(backgroundImg, MAX_IMAGE_SIZE);
    }

    public static Bitmap resizeBitmap(Bitmap inputBitmap, int maxImageSize) {
        float ratio = Math.min(
                (float) maxImageSize / inputBitmap.getWidth(),
                (float) maxImageSize / inputBitmap.getHeight());
        int width = Math.round(ratio * inputBitmap.getWidth());
        int height = Math.round(ratio * inputBitmap.getHeight());

        return Bitmap.createScaledBitmap(inputBitmap, width,
                height, true);
    }

Does this necessary, or it's bug?

无法添加依赖

Android resource linking failed
Output:  /Users/l/nutstore-android-scanner/app/build/intermediates/incremental/merge360DebugResources/merged.dir/values-v28/values-v28.xml:7: error: resource android:attr/dialogCornerRadius not found.
/Users/l/nutstore-android-scanner/app/build/intermediates/incremental/merge360DebugResources/merged.dir/values-v28/values-v28.xml:11: error: resource android:attr/dialogCornerRadius not found.
/Users/l/nutstore-android-scanner/app/build/intermediates/incremental/merge360DebugResources/merged.dir/values/values.xml:1460: error: resource android:attr/fontVariationSettings not found.
/Users/l/nutstore-android-scanner/app/build/intermediates/incremental/merge360DebugResources/merged.dir/values/values.xml:1461: error: resource android:attr/ttcIndex not found.
error: failed linking references.

Command: /Users/l/.gradle/caches/transforms-1/files-1.1/aapt2-3.2.1-4818971-osx.jar/476c266d41ea4fead5273b51b58e0dce/aapt2-3.2.1-4818971-osx/aapt2 link -I\
        /Users/l/Library/Android/sdk/platforms/android-27/android.jar\
        --manifest\
        /Users/l/nutstore-android-scanner/app/build/intermediates/merged_manifests/360Debug/process360DebugManifest/merged/AndroidManifest.xml\
        -o\
        /Users/l/nutstore-android-scanner/app/build/intermediates/processed_res/360Debug/process360DebugResources/out/resources-360Debug.ap_\
        -R\
        @/Users/l/nutstore-android-scanner/app/build/intermediates/incremental/process360DebugResources/resources-list-for-resources-360Debug.ap_.txt\
        --auto-add-overlay\
        --java\
        /Users/l/nutstore-android-scanner/app/build/generated/not_namespaced_r_class_sources/360Debug/process360DebugResources/r\
        --proguard-main-dex\
        /Users/l/nutstore-android-scanner/app/build/intermediates/legacy_multidex_aapt_derived_proguard_rules/360Debug/process360DebugResources/manifest_keep.txt\
        --custom-package\
        nutstore.android.scanner\
        -0\
        apk\
        --output-text-symbols\
        /Users/l/nutstore-android-scanner/app/build/intermediates/symbols/360/debug/R.txt\
        --no-version-vectors
Daemon:  AAPT2 aapt2-3.2.1-4818971-osx Daemon #0

不能换行

水印不能换行,1、当文字多了的时候,希望能换行。2、当有回车换行符的时候希望能正常显示水印。

Update the demo gifs in README.md.

We have two gifs in the invisible watermark section, with the code comes to the newer version, the demo gifs have been out of date, I think we can update it using the newest version of demo.

All you need is to:

  • Fork this repo and compile it in your own machine.
  • Run the latest demo apk in a real android device or an emulator.
  • Record the screen using adb, and convert it to two gif pictures.
  • Update the gifs in README.md and README-CN.md.

Note: The gifs cannot be too large or it will take a really long time to load.

Package size optimization.

The FFT operation is really fast while using the library: JTransforms, but the package size is too large. We need to implement the FFT using C++ by our self. Maybe we can set two versions of the androidwm.

Like this:

  • androidwm with invisible watermarks
  • androidwm without invisible watermarks

怎么适配图片大小

不同大小的图片,有的图片会溢出,怎么计算水印的长度,再去设置位置?或者要是能实现设置右边距、下边距这样最好!

水印的密度

使用 覆盖模式 时,水印覆盖的密度比文档中显示的要密集。
请问有没有办法调节呢

OOM in LSBDetectionTask

When using StringBuilder to build a very long string from an array, the method intArrayToString will throws an Out of Memory exception.

Solution

divide the input array to multiple subarrays, and use different StringBuilder to append the strings together.

Update the document.

  • Update the new method and args in REDAME.md
  • Create a new .md file to describe the principles behind the invisible watermarks.

IllegalArgumentException: width and height must be > 0

Caused by: java.lang.IllegalArgumentException: width and height must be > 0
        at android.graphics.Bitmap.createBitmap(Bitmap.java:810)
        at android.graphics.Bitmap.createBitmap(Bitmap.java:789)
        at android.graphics.Bitmap.createBitmap(Bitmap.java:720)
        at com.watermark.androidwm.utils.BitmapUtils.resizeBitmap(BitmapUtils.java:153)
        at com.watermark.androidwm.Watermark.createWatermarkImage(Watermark.java:153)
        at com.watermark.androidwm.Watermark.<init>(Watermark.java:94)
        at com.watermark.androidwm.WatermarkBuilder.setInvisibleWMListener(WatermarkBuilder.java:253)
        at com.example.huangyz0918.myapplication.MainActivity.onCreate(MainActivity.java:35)
        at android.app.Activity.performCreate(Activity.java:5990)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)

in method resizeBitmap().

Image upgrade

Hi, I can see that you a simple logo. What do you think about having an image upgrade (A banner for the GitHub project or any other graphics that your app would need).

I can sent you some drafts if you like. I`m thinking about some ideas, I can send you some drafts in a few hours

Let me know what do you think.

release

请问有demo的release版本app吗?很想找一个盲水印的app

Support for vector drawables

When creating a WatermarkImage with a vector drawable resource, generating the final watermark via:

WatermarkBuilder.create(context, backgroundBitmap) .loadWatermarkImage(waterMarkImage) .getWatermark()

throws a NullPointerException

Here is the full stacktrace:

java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
2020-11-03 10:50:39.603 2574-2754/com.buckdown.android W/System.err: at com.watermark.androidwm_light.utils.BitmapUtils.resizeBitmap(BitmapUtils.java:124)
2020-11-03 10:50:39.603 2574-2754/com.buckdown.android W/System.err: at com.watermark.androidwm_light.Watermark.createWatermarkImage(Watermark.java:112)
2020-11-03 10:50:39.603 2574-2754/com.buckdown.android W/System.err: at com.watermark.androidwm_light.Watermark.(Watermark.java:75)

Build failed

CMake Error: CMake was unable to find a build program corresponding to "Ninja". CMAKE_MAKE_PROGRAM is not set. You probably need to select a different build tool.

enhance the robustness of LSB watermark

LSB has a very weak robustness, so we need to make it better.

Proposal

  • cover the watermark into the whole background image.
  • using the interlaced RGB color.

Requested array size exceeds VM limit

In the LSBWatermarkTask :

  int[] rebuiltPixels = new int[backgroundPixels.length];

We will get a out of memory error while init a large int array.

  Caused by: java.lang.OutOfMemoryError: Failed to allocate a 10485772 byte allocation with 9612332 free bytes and 9MB until OOM
        at com.watermark.androidwm.task.LSBWatermarkTask.doInBackground(LSBWatermarkTask.java:122)
        at com.watermark.androidwm.task.LSBWatermarkTask.doInBackground(LSBWatermarkTask.java:40)
        at android.os.AsyncTask$2.call(AsyncTask.java:292)

Consider using a BitSet to refactor the code.

使用时偶现java.lang.OutOfMemoryError

在使用该水印功能时,低概率会出现内存溢出的问题,这个能解决下吗?
java.lang.OutOfMemoryError
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:1165)
at android.graphics.Bitmap.createBitmap(Bitmap.java:1115)
at android.graphics.Bitmap.createBitmap(Bitmap.java:1065)
at android.graphics.Bitmap.createBitmap(Bitmap.java:1026)
at com.watermark.androidwm_light.Watermark.createWatermarkText(Watermark.java:159)
at com.watermark.androidwm_light.Watermark.(Watermark.java:85)
at com.watermark.androidwm_light.WatermarkBuilder.getWatermark(WatermarkBuilder.java:250)
at com.csi.sec.utils.WaterMarkUtils.getWaterMarkBitmap(WaterMarkUtils.java:266)
at com.csi.sec.utils.WaterMarkUtils.getDefaultWaterMarkBitmap(WaterMarkUtils.java:164)
at com.csi.sec.workspace.meeting.activity.InviteesActivity.setWatermark(InviteesActivity.java:483)
at com.csi.sec.workspace.meeting.activity.InviteesActivity.access$1500(InviteesActivity.java:86)
at com.csi.sec.workspace.meeting.activity.InviteesActivity$4.onGlobalLayout(InviteesActivity.java:472)
at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:1082)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3210)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2225)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9126)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:999)
at android.view.Choreographer.doCallbacks(Choreographer.java:797)
at android.view.Choreographer.doFrame(Choreographer.java:732)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:984)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8167)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)

关于透明图片设置水印

老哥,我使用一张透明的图片设置水印之后图片变成了黑色,要保持它的透明度需要什么特殊的处理吗

This is caused by library dependencies that have been compiled using Java 8 or above.

新建项目之后,使用数字水印有如下报错:

Error:Error converting bytecode to dex:
Cause: Dex cannot parse version 52 byte code.
This is caused by library dependencies that have been compiled using Java 8 or above.
If you are using the 'java' gradle plugin in a library submodule add 
targetCompatibility = '1.7'
sourceCompatibility = '1.7'
to that submodule's build.gradle file.

尝试了网上的方法添加:

compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }

以及

jackOptions {
        enabled true
    }

仍然不行,想请问要怎么解决

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.