如何在现有图像上添加水印

时间:2010-11-01 10:16:34

标签: ios objective-c image

我发现了一些代码如下:

 UIGraphicsBeginImageContext(CGSizeMake(320, 480));
// This is where we resize captured image
[(UIImage *)[info objectForKey:UIImagePickerControllerOriginalImage] 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();

但我不确定这是否是最佳方式。

4 个答案:

答案 0 :(得分:7)

检查CGImageCreateWithMask

将现有图像和水印图像传递给此功能

- (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];

}

答案 1 :(得分:2)

有不同类型的水印:可见和不可见水印。因为你没有明确提到你需要一个可见的水印,我将提供一个不可见水印的解决方案。这种理论很简单:取最低优先级的位并在那里添加水印。

在iPhone编程中,它将是这样的:

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;
  }
}

编码反之亦然 - 您可以使用此代码宽度存储* height * 3位图像中的位。即对于640x480图像,将是996字节 它可以存储每个像素更多的位,但在这种情况下也会丢失更多细节(然后你需要更改掩码0x01)。 alpha通道也可以用来存储几个位 - 为了简单起见,我把它留在了这里......

答案 2 :(得分:1)

对于这种事情,最广泛使用的库可能叫做Imagemagick。 How to watermark.

答案 3 :(得分:1)

我认为你不需要一个库来做这件事。对于这么简单的事情来说太过分了。至少OmnipotentEntity提出的图书馆在我看来太多了。

您尝试的方法简单而且好。 即使它不起作用,你也可以自己动手。混合是一种非常简单的算法。

来自WikiPedia:

alt text

  

其中Co是结果   操作,Ca是颜色的   元素A中的像素,Cb是颜色   元素B中的像素,以及αa和αb   是像素的alpha   元素A和B分别

我打算写如何访问像素,但康斯坦丁已经做到了!