2012-03-13 39 views

Trả lời

3

nghĩa là trừ một hình ảnh là gì? hình ảnh mẫu cho thấy nhiều hơn một hoạt động màu đỏ! chúng ta hãy nói rằng để trừ hình ảnh một từ hình ảnh b có nghĩa là để thiết lập mỗi điểm ảnh trong b mà cắt một điểm ảnh trong một để minh bạch. để thực hiện phép trừ, những gì chúng ta thực sự đang làm là che hình ảnh b sang nghịch đảo của hình ảnh a. do đó, một cách tiếp cận tốt là tạo mặt nạ hình ảnh từ kênh alpha của hình a, sau đó áp dụng nó cho b. để tạo mặt nạ, bạn sẽ làm như sau:

// get access to the image bytes 
CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage)); 

// create a buffer to hold the mask values 
size_t width = CGImageGetWidth(image.CGImage); 
size_t height = CGImageGetHeight(image.CGImage);  
uint8_t *maskData = malloc(width * height); 

// iterate over the pixel data, reading the alpha value 
uint8_t *alpha = (uint8_t *)CFDataGetBytePtr(pixelData) + 3; 
uint8_t *mask = maskData; 
for (int y = 0; y < height; y++) { 
    for (int x = 0; x < width; x++) { 
     *mask = *alpha; 
     mask++;  
     alpha += 4; // skip to the next pixel 
    } 
} 

// create the mask image from the buffer 
CGDataProviderRef maskProvider = CGDataProviderCreateWithData(NULL, maskData, width * height, NULL); 
CGImageRef maskImage = CGImageMaskCreate(width, height, 8, 8, width, maskProvider, NULL, false); 

// cleanup 
CFRelease(pixelData); 
CFRelease(maskProvider); 
free(maskData); 

whew. sau đó, để che hình ảnh b, tất cả những gì bạn phải làm là:

CGImageRef subtractedImage = CGImageCreateWithMask(b.CGImage, maskImage); 

hey presto.

+0

ví dụ điển hình - điều này phù hợp với tôi. cảm ơn! –

3

Để nhận các kết quả đó, hãy sử dụng hình ảnh thứ hai làm mặt nạ khi bạn vẽ hình ảnh đầu tiên. Đối với loại bản vẽ này, bạn sẽ cần phải sử dụng Đồ họa cốt lõi, a.k.a. Quartz 2D. Hướng dẫn lập trình 2D Quartz 2D có một phần được gọi là Bitmap Images and Image Masks sẽ cho bạn biết mọi thứ bạn cần biết.

Bạn đang hỏi về các đối tượng UIImage, nhưng để sử dụng Core Graphics, bạn sẽ cần CGImages thay thế. Không có vấn đề gì - UIImage cung cấp thuộc tính CGImage cho phép bạn lấy dữ liệu bạn cần một cách dễ dàng.

13

Tôi tin rằng bạn có thể thực hiện việc này bằng cách sử dụng chế độ hòa trộn kCGBlendModeDestinationOut. Tạo một bối cảnh mới, vẽ hình nền của bạn, sau đó vẽ hình nền trước bằng chế độ hòa trộn này.

UIGraphicsBeginImageContextWithOptions(sourceImage.size, NO, sourceImage.scale) 
[sourceImage drawAtPoint:CGPointZero]; 
[maskImage drawAtPoint:CGPointZero blendMode:kCGBlendModeDestinationOut alpha:1.0f]; 
UIImage *result = UIGraphicsGetImageFromCurrentImageContext() 
UIGraphicsEndImageContext(); 
+0

+1: Bạn nên cố gắng thực hiện việc này. Sạch hơn và đơn giản hơn nhiều so với câu trả lời được chấp nhận. – sjwarner

+0

Vì vậy, tôi sẽ, khá trơn. – Tark

+1

Đúng, đây phải là câu trả lời được chấp nhận. –

0

Giải pháp của Kevin Ballard làm việc cho tôi! Trong Swift 3.x:

func subtract(source: UIImage, mask: UIImage) -> UIImage? { 
    UIGraphicsBeginImageContextWithOptions(source.size, false, source.scale) 
    source.draw(at: CGPoint.zero) 
    mask.draw(at: CGPoint.zero, blendMode: .destinationOut, alpha: 1.0) 
    let result = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 
    return result 
} 
Các vấn đề liên quan