开发者

how to add watermark on a exist image

I found some code as follows:

 UIGraphicsBeginImageContext(CGSizeMake(320, 480));
// This is where we resize captured image
[(UIImage *)[info objectForKey:UIImagePickerControllerOriginalImag开发者_如何学Goe] drawInRect:CGRectMake(0, 0, 320, 480)];
// And add the watermark on top of it
[[UIImage imageNamed:@"Watermark.png"] drawAtPoint:CGPointMake(0, 0) blendMode:kCGBlendModeNormal alpha:WATERMARK_ALPHA];
// Save the results directly to the image view property
imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

but I am not sure whether it's the best way.


Check CGImageCreateWithMask.

Pass the existing image and the watermark image to this function

- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {

    CGImageRef maskRef = maskImage.CGImage; 

    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                             CGImageGetHeight(maskRef),
                                        CGImageGetBitsPerComponent(maskRef),
                                        CGImageGetBitsPerPixel(maskRef),
                                        CGImageGetBytesPerRow(maskRef),
                                        CGImageGetDataProvider(maskRef), NULL, false);

    CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);

    return [UIImage imageWithCGImage:masked];

}


There are different types of watermarking: visible and non visible watermarking. Because you didn't mentioned explicit you want a visible watermark, I will provide a solution for a non-visible watermark. The Theory of thiss kind of simple: Take the bits with the lowest priority and add your watermark there.

In iPhone programming it would be something like this:

CGContextRef context = [self createARGBBitmapContextFromImage:yourView.image.CGImage];
unsigned char* data = CGBitmapContextGetData (context);
size_t width = CGImageGetWidth(yourView.image.CGImage);
size_t height = CGImageGetHeight(yourView.image.CGImage);
for (int y=0; y<height; y++) {
  for (int x=0; x<width; x++) {
    int pos = y*width + x;
    int argb = data[pos];
    int r = (argb >> 16) & 0xff;
    int g = (argb >>  8) & 0xff;
    int b =  argb        & 0xff;

    //add watermark to the bits with the lowest priority
    unsigned char bit1 = 0x00 , bit2 = 0x01, bit3 = 0x00;
    //example adds false, true, false to every pixel - only 0x00 and 0x01 should be used here (1 bit)
    unsigned char mask = 0x01;

    r = (r - (r & mask)) + bit1;
    g = (g - (g & mask)) + bit2;
    b = (b - (b & mask)) + bit3;
    data[pos] = (0xFF<<24) | (r<<16) | (g<<8) | b;
  }
}

The encoding would be vice-versa exactly the same - you could store with this code width*height*3 Bits in your image. I.e. for an 640x480 image that would be 996 Bytes It can store more bits per pixel, but will also loses more details in this case (then you need to change the mask 0x01). And the alpha channel could be also used to store a few bits as well - for simplicity I leaved that out here...


Probably the most widely used library for this sort of thing is called Imagemagick. How to watermark.


I don't think you need a library for doing that. It is just too much for such a simple thing. At least the library proposed by OmnipotentEntity is too much in my opinion.

The approach you are trying is simple and good. Even if it does not work you could do it yourself. Blending is a very simple algorithm.

From WikiPedia:

how to add watermark on a exist image

where Co is the result of the operation, Ca is the color of the pixel in element A, Cb is the color of the pixel in element B, and αa and αb are the alpha of the pixels in elements A and B respectively

I was going to write how to access pixels but Constantin already did it!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜