Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Git
.git
.gitignore

# Docker
Dockerfile
.dockerignore

# Python
__pycache__/
*.pyc
*.pyo
*.pyd

# Virtual environment
venv/
.venv/

# IDE / Editor
.idea/
.vscode/
20 changes: 20 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Python
__pycache__/
blind_watermark/__pycache__/
*.pyc
*.pyo
*.pyd

# Virtual environment
venv/
.venv/

# IDE / Editor
.idea/
.vscode/

# Uploads folder
uploads/

# OS-specific
.DS_Store
23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Use an official Python runtime as a parent image
FROM python:3.12-slim

# Set the working directory in the container
WORKDIR /app

# Copy the requirements file into the container
COPY requirements.txt .

# Install system dependencies required by OpenCV
RUN apt-get update && apt-get install -y libgl1 libglib2.0-0

# Install dependencies
RUN pip install --no-cache-dir -r requirements.txt

# Copy the rest of the application code
COPY . .

# Expose the port the app runs on
EXPOSE 5891

# Run the application
CMD ["python", "web_app.py"]
195 changes: 60 additions & 135 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,177 +1,102 @@



# blind-watermark

Blind watermark based on DWT-DCT-SVD.


[![PyPI](https://img.shields.io/pypi/v/blind_watermark)](https://pypi.org/project/blind_watermark/)
[![Build Status](https://travis-ci.com/guofei9987/blind_watermark.svg?branch=master)](https://travis-ci.com/guofei9987/blind_watermark)
[![codecov](https://codecov.io/gh/guofei9987/blind_watermark/branch/master/graph/badge.svg)](https://codecov.io/gh/guofei9987/blind_watermark)
[![License](https://img.shields.io/pypi/l/blind_watermark.svg)](https://github.com/guofei9987/blind_watermark/blob/master/LICENSE)
![Python](https://img.shields.io/badge/python->=3.5-green.svg)
![Platform](https://img.shields.io/badge/platform-windows%20|%20linux%20|%20macos-green.svg)
[![stars](https://img.shields.io/github/stars/guofei9987/blind_watermark.svg?style=social)](https://github.com/guofei9987/blind_watermark/)
[![fork](https://img.shields.io/github/forks/guofei9987/blind_watermark?style=social)](https://github.com/guofei9987/blind_watermark/fork)
[![Downloads](https://pepy.tech/badge/blind-watermark)](https://pepy.tech/project/blind-watermark)
[![Discussions](https://img.shields.io/badge/discussions-green.svg)](https://github.com/guofei9987/blind_watermark/discussions)
<a href="https://hellogithub.com/repository/guofei9987/blind_watermark" target="_blank"><img src="https://abroad.hellogithub.com/v1/widgets/recommend.svg?rid=3834302ff46a40f188a651ef8bd26ff5&claim_uid=se0WHo8cbiLv2w1&theme=small" alt="Featured|HelloGitHub" /></a>

- **Documentation:** [https://BlindWatermark.github.io/blind_watermark/#/en/](https://BlindWatermark.github.io/blind_watermark/#/en/)
- **文档:** [https://BlindWatermark.github.io/blind_watermark/#/zh/](https://BlindWatermark.github.io/blind_watermark/#/zh/)
- **中文 readme** [README_cn.md](README_cn.md)
- **Source code:** [https://github.com/guofei9987/blind_watermark](https://github.com/guofei9987/blind_watermark)



# install
```bash
pip install blind-watermark
```

For the current developer version:
```bach
git clone git@github.com:guofei9987/blind_watermark.git
cd blind_watermark
pip install .
```

# How to use
- **中文文档:** [https://BlindWatermark.github.io/blind_watermark/#/zh/](https://BlindWatermark.github.io/blind_watermark/#/zh/)

# Quick Start: Web App

## Use in bash
For ease of use, this project includes a modern web interface.

## How to Run

```bash
# embed watermark into image:
blind_watermark --embed --pwd 1234 examples/pic/ori_img.jpeg "watermark text" examples/output/embedded.png
# extract watermark from image:
blind_watermark --extract --pwd 1234 --wm_shape 111 examples/output/embedded.png
```
### Option 1: Run with Docker (Recommended)
This is the simplest and recommended method to avoid local environment issues.

1. **Start the Application:**
In the project root directory, run the following command:
```bash
docker-compose up -d
```

2. **Access the Application:**
Open your browser and navigate to `http://localhost:5891`.

## Use in Python
3. **Stop the Application:**
In the terminal, press `Ctrl+C`, then run the following command to clean up the containers:
```bash
docker-compose down
```

Original Image + Watermark = Watermarked Image
### Option 2: Run Natively

![origin_image](docs/原图.jpeg) + '@guofei9987 开源万岁!' = ![打上水印的图](docs/打上水印的图.jpg)
1. **Install Dependencies:**
```bash
pip install -r requirements.txt
```

2. **Start the Server:**
```bash
python web_app.py
```

See the [codes](/examples/example_str.py)
3. **Access the Application:**
Open your browser and navigate to `http://localhost:5891`.

Embed watermark:
```python
from blind_watermark import WaterMark

bwm1 = WaterMark(password_img=1, password_wm=1)
bwm1.read_img('pic/ori_img.jpg')
wm = '@guofei9987 开源万岁!'
bwm1.read_wm(wm, mode='str')
bwm1.embed('output/embedded.png')
len_wm = len(bwm1.wm_bit)
print('Put down the length of wm_bit {len_wm}'.format(len_wm=len_wm))
```
# Advanced Usage (CLI & Library)

Extract watermark:
```python
bwm1 = WaterMark(password_img=1, password_wm=1)
wm_extract = bwm1.extract('output/embedded.png', wm_shape=len_wm, mode='str')
print(wm_extract)
## Installation
```bash
pip install blind-watermark
```
Output:
>@guofei9987 开源万岁!

### attacks on Watermarked Image


|attack method|image after attack|extracted watermark|
|--|--|--|
|Rotate 45 Degrees|![旋转攻击](docs/旋转攻击.jpg)|'@guofei9987 开源万岁!'|
|Random crop|![截屏攻击](docs/截屏攻击2_还原.jpg)|'@guofei9987 开源万岁!'|
|Masks| ![多遮挡攻击](docs/多遮挡攻击.jpg) |'@guofei9987 开源万岁!'|
|Vertical cut|![横向裁剪攻击](docs/横向裁剪攻击_填补.jpg)|'@guofei9987 开源万岁!'|
|Horizontal cut|![纵向裁剪攻击](docs/纵向裁剪攻击_填补.jpg)|'@guofei9987 开源万岁!'|
|Resize|![缩放攻击](docs/缩放攻击.jpg)|'@guofei9987 开源万岁!'|
|Pepper Noise|![椒盐攻击](docs/椒盐攻击.jpg)|'@guofei9987 开源万岁!'|
|Brightness 10% Down|![亮度攻击](docs/亮度攻击.jpg)|'@guofei9987 开源万岁!'|


## Usage as a CLI Tool
```bash
# Embed watermark into an image:
blind_watermark --embed --pwd 1234 examples/pic/ori_img.jpeg "watermark text" examples/output/embedded.png




### embed images

embed watermark:
```python
from blind_watermark import WaterMark

bwm1 = WaterMark(password_wm=1, password_img=1)
# read original image
bwm1.read_img('pic/ori_img.jpg')
# read watermark
bwm1.read_wm('pic/watermark.png')
# embed
bwm1.embed('output/embedded.png')
# Extract watermark from an image:
blind_watermark --extract --pwd 1234 --wm_shape 111 examples/output/embedded.png
```

## Usage as a Python Library
See the [examples directory](/examples/) for more details.

Extract watermark:
**Example: Text Watermark**
```python
bwm1 = WaterMark(password_wm=1, password_img=1)
# notice that wm_shape is necessary
bwm1.extract(filename='output/embedded.png', wm_shape=(128, 128), out_wm_name='output/extracted.png', )
```


|attack method|image after attack|extracted watermark|
|--|--|--|
|Rotate 45 Degrees|![旋转攻击](docs/旋转攻击.jpg)|![](docs/旋转攻击_提取水印.png)|
|Random crop|![截屏攻击](docs/截屏攻击2_还原.jpg)|![多遮挡_提取水印](docs/多遮挡攻击_提取水印.png)|
|Mask| ![多遮挡攻击](docs/多遮挡攻击.jpg) |![多遮挡_提取水印](docs/多遮挡攻击_提取水印.png)|


### embed array of bits
from blind_watermark import WaterMark

See it [here](/examples/example_bit.py)
bwm = WaterMark(password_img=1, password_wm=1)
bwm.read_img('pic/ori_img.jpg')
bwm.read_wm('Hello World', mode='str')
bwm.embed('output/embedded.png')

# To extract, you need the length of the watermark bit string
len_wm = len(bwm.wm_bit)
print(f"Watermark length to use for extraction: {len_wm}")

As demo, we embed 6 bytes data:
```python
wm = [True, False, True, True, True, False]
wm_extract = bwm.extract('output/embedded.png', wm_shape=len_wm, mode='str')
print(f"Extracted watermark: {wm_extract}")
```

Embed:
**Example: Image Watermark**
```python
from blind_watermark import WaterMark

bwm1 = WaterMark(password_img=1, password_wm=1)
bwm1.read_ori_img('pic/ori_img.jpg')
bwm1.read_wm([True, False, True, True, True, False], mode='bit')
bwm1.embed('output/embedded.png')
```
bwm = WaterMark(password_img=1, password_wm=1)
bwm.read_img('pic/ori_img.jpg')
bwm.read_wm('pic/watermark.png', mode='img') # Use a watermark image
bwm.embed('output/embedded_with_img_wm.png')

Extract:
```python
bwm1 = WaterMark(password_img=1, password_wm=1, wm_shape=6)
wm_extract = bwm1.extract('output/打上水印的图.png', mode='bit')
print(wm_extract)
# To extract, you need the shape of the watermark image (height, width)
wm_shape = (128, 128) # Example shape
bwm.extract('output/embedded_with_img_wm.png', wm_shape=wm_shape, out_wm_name='output/extracted_wm.png', mode='img')
```
Notice that `wm_shape` (shape of watermark) is necessary

The output `wm_extract` is an array of float. set a threshold such as 0.5.


# Concurrency

```python
WaterMark(..., processes=None)
```
- `processes` number of processes, can be integer. Default `None`, which means using all processes.

## Related Project

- text_blind_watermark (Embed message into text): [https://github.com/guofei9987/text_blind_watermark](https://github.com/guofei9987/text_blind_watermark)
- HideInfo(hide as image, hide as sounds, hide as text):[https://github.com/guofei9987/HideInfo](https://github.com/guofei9987/HideInfo)
Loading