Ji Chang Xin Big guy early!

Source code

IOS -- Realization of invisible watermark and algorithm of "color deepening"

Many APP have watermark on sensitive pages. In order to catch up with public opinion, they can trace the source of pictures. Generally, there are ID or nicknames on the watermark.


The purpose of watermarking is summarized as follows:

  1. Tracking source

  2. Deterrent effect

Deterrence means that when users see watermark, they will consciously avoid illegal acts.

However, when there is no need for deterrence, for example, in order to keep the application or the beauty of the picture, the highlighted watermark does not seem necessary. At this time, the invisible watermark can be considered.

Recently, I saw a watermark on my colleague's knowledge.

As shown below, there seems to be no watermark on the surface.


But after the PS mixed color mode is processed, the invisible watermark is displayed.

 Image.png The specific way of handling is

  1. Add all black layers on the original map.

  2. The whole black layer is selected to "deepen the color".

So far, I have been curious about the algorithm of PS. Blending mode is a common tool, but I haven't noticed the formula before.

Color blending mode

The blending mode of PS is actually the result layer obtained from a series of calculations after each pixel of the base map and the mixed layer.

After reading a series of data, I find that the existing formulas are incorrect, and some popular articles are not right either. The PS official document only introduced several mixed color models, but no formula was given.

Look at the color information in each channel and darken the base color to reflect the blend color by increasing the contrast between the two. Mixed with white does not change.


The formula is more problematic.

Result color = base color - [255- base color] x (255- mixed color)] / mixed color

The formulas (255- primaries) and (255- mixed colors) are inverting primaries and mixed colors respectively.

  1. If the mixed color is 0 (black), and the (base color mixed color) is 0, the value obtained is a negative value of 0, so whatever the primary color is, the value is 0.

  2. When the mixed color value is 255 (white), the mixed color is the same as the base color.

Basically, the algorithm formula has a fatal problem. The formulas are all marked. Any color and black mixed color are black. This is obviously not consistent with the result of PS in the above. If this theory is applied, the whole picture should be black.

Finally, I tried out a close plan.

  1. Result color = primary color - (primary color reverse phase mixed color inverse) / mixed color.

  2. If the mixed layer is black, it is considered that RGB is (255, 255, 255), that is, very deep gray.

This formula can basically achieve the effect of color deepening in PS. It can turn light into darker and darker.

Realization of invisible watermark

Add watermark

First, the basic image processing methods in iOS are introduced.

  1. Get all pixels of the picture.

  2. Changing pixel information pointing to pointer

 + (UIImage *) addWatermark: (UIImage *) image
text: (NSString *) text ({
UIFont * *font) = [UIFont systemFontOfSize:32]; 
NSDictionary = =, 0, 0; 0 =; 0 =; 0 =; Text:text
textPoint:CGPointMake (x, y) 
idx0 + +; 
x = 0; 
idx0 = 0; 
idx1 + +; 
return newImage;}} + (UIImage *) ((*)) ((* *)) ((* *)) ((* *)) (()) (* *) * ((* *));

Display watermark

The watermark can be displayed through the formula mentioned above.

 The parameters are: length, width, height, the number of bytes per pixel (4), the number of bits per pixel, the number of bits per pixel, the number of bits per pixel, and the number of bits per pixel; the number of bits is = (4); the number of bits per byte is UIImage; the area of the memory area is up to the first pixel address = = (* *) ((* *)); + (UIImage *) visibleWatermark: (UIImage *) image {/ / 1. Get the raw pixels of the image
// defines 32 bits. InputBytesPerRow, colorSpace, 
kCGImageAlphaPremultipliedLast kCGBitmapByteOrder32Big); 
CGContextDrawImage / context / 
CGContextDrawImage (context, CGRectMake (0, 0, inputWidth, inputHeight), inputCGImage) according to the pixel at the current interface; 
for / pixel processing 
for (
for = 0;; < < 0); ; 
thisG = G (color); 
thisG = G (color); 
thisB = B (color); 
thisA = A; (f) = {{}}; {{}}}}; = = (4.); (2)}}}} / /; (2)} {}}} / / create (new,), or create new map / / D (/); * * * = {()); * * * = {}; * / / release / / 5.; 
thisR = R (color) * mixed color Invert) / mixed color 
int mixValue = 1; 
int resultValue = 0; 
if (mixValue = = 0) {
resultValue = 0;} else {
resultValue = originValue - (255 - originValue) * (255 - originValue) / {{} = 0;

Code and open source library

In order to facilitate the use of an open source library, the package is very practical, with DEMO


Author: little fish Zhou Lingyu

Link: https://juejin.im/post/5cd17612f265da037a3d0183

Fabulous ( Zero )

This article is composed of Contributor Creation, article address: Https://blog.isoyu.com/archives/iosyinxingshuiyindeshixianheyansejiashensuanfa.html
Use Knowledge sharing signature 4 The international license agreement is licensed. In addition to the reprint / provenance, all originals or translations of this site must be signed before retransmission. The final editing time is May, 23, 2019 at 06:13 afternoon.

Hot articles




Please wait three seconds after submission, so as not to cause unsuccessful successes and duplication.