2009-08-21 38 views
31

Tôi đang cố gắng hòa trộn nền với hình ảnh nền trước, nơi hình ảnh nền trước là một hình ảnh trong suốt với các dòng trên đó.kết hợp hai hình ảnh dựa trên độ alpha/độ trong của hình ảnh trên cùng

Tôi đang cố gắng thực hiện theo cách này.

UIGraphicsBeginImageContext(CGSizeMake(320, 480)); 
CGContextRef context = UIGraphicsGetCurrentContext(); 

// create rect that fills screen 
CGRect bounds = CGRectMake(0,0, 320, 480); 

// This is my bkgnd image 
CGContextDrawImage(context, bounds, [UIImage imageNamed:@"bkgnd.jpg"].CGImage); 

CGContextSetBlendMode(context, kCGBlendModeSourceIn); 

// This is my image to blend in 
CGContextDrawImage(context, bounds, [UIImage imageNamed:@"over.png"].CGImage); 

UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext(); 

UIImageWriteToSavedPhotosAlbum(outputImage, self, nil, nil); 
// clean up drawing environment 
// 
UIGraphicsEndImageContext(); 

nhưng dường như không hoạt động.

Mọi đề xuất sẽ được đánh giá cao.

+0

Chú thích chuyên môn: đây là đề cập đến "hòa trộn kênh alpha" (hợp lại hai hình ảnh dựa trên một kênh alpha tại một trong những hình ảnh), * không * để sử dụng Core Đồ họa "chế độ pha trộn" - tìm kiếm lại nếu đó là những gì bạn cần. Trên thực tế, [Câu trả lời của Eric] (http://stackoverflow.com/a/3188761/199364) hiển thị ngắn gọn việc sử dụng một chế độ hòa trộn; bạn có thể thay thế một chế độ hòa trộn khác ở đó và xóa "alpha: 0.8 "tham số. – ToolmakerSteve

Trả lời

0

Bạn có thể sử dụng UIImage 's drawInRect: hoặc drawAtPoint: thay vì CGContextDrawImage (chúng vẽ theo ngữ cảnh hiện tại). Việc sử dụng chúng có cung cấp cho bạn bất kỳ sự khác biệt nào về đầu ra không?

Cũng có thể hữu ích khi đảm bảo giá trị UIImage* bạn đang nhận được từ imageNamed: hợp lệ.

1

Bạn có thể cung cấp chi tiết về ý nghĩa của từ "nó có vẻ không hoạt động không?" Nó chỉ vẽ một hình ảnh hay hình ảnh khác? Vẽ màu đen? Tiếng ồn? Tai nạn? Tại sao bạn chọn kCGBlendModeSourceIn; bạn đang cố gắng đạt được hiệu quả gì (có hàng chục cách để pha trộn hình ảnh)? Hình ảnh của bạn đã có alpha chưa?

Tôi cho rằng những gì bạn đang cố gắng làm là trộn hai hình ảnh sao cho mỗi hình ảnh có độ mờ là 50%? Sử dụng CGContextSetAlpha() cho điều đó thay vì CGContextSetBlendMode().

+0

Cảm ơn bạn đã trả lời .... Cả hai hình ảnh của tôi có độ mờ 100% .... khi tôi pha trộn cả hai hình ảnh ... ngữ cảnh của tôi chỉ vẽ hình ảnh thứ hai ... trong macosx ... i sử dụng nguồn trên bộ lọc để tổng hợp cả hình ảnh .... và hình ảnh thứ hai mà tôi muốn kết hợp đã alpha rồi. –

+0

Tôi tin rằng bạn muốn quay lại và nghiên cứu các khái niệm cơ bản về bản vẽ Quartz. Tôi tin rằng bạn đang có sự nhầm lẫn về ý nghĩa của việc vẽ các lớp khác nhau với alpha của chúng so với những gì nó có nghĩa là pha trộn (có liên quan, nhưng khác với cách nó được triển khai). để bạn có thể làm những gì mình muốn một cách dễ dàng và có hiệu suất tốt, khả năng dự đoán và tính linh hoạt. http://developer.apple.com/documentation/graphicsimaging/conceptual/drawingwithquartz2d/ –

19
UIImage* bottomImage = [UIImage imageNamed:@"bottom.png"]; 
UIImage* topImage = [UIImage imageNamed:@"top.png"]; 
UIImageView* imageView = [[UIImageView alloc] initWithImage:bottomImage]; 
UIImageView* subView = [[UIImageView alloc] initWithImage:topImage]; 
subView.alpha = 0.5; // Customize the opacity of the top image. 
[imageView addSubview:subView]; 
UIGraphicsBeginImageContext(imageView.frame.size); 
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage* blendedImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
[subView release]; 
[imageView release]; 

[self doWhateverIWantWith: blendedImage]; 
+0

Cảm ơn bạn đã trả lời .... nhưng không phải là điều này giống như có opacity 50% ... mayb cách thức mà tôi phrased câu hỏi của tôi là sai ... mayb i shld nói tôi muốn hợp nhất 2 UIImages ... và hình ảnh trên đầu trang có giá trị alpha. –

+1

Nếu có giá trị alpha trong tệp png của hình ảnh trên cùng, chỉ cần bỏ "subView.alpha = 0.5;" và nó sẽ vẽ hình ảnh trên cùng, bao gồm cả giá trị alpha tùy chỉnh, ở trên cùng của hình ảnh dưới cùng. – Tyler

+0

Làm việc tuyệt vời, cảm ơn. – zekel

4

Trộn với alpha

UIGraphicsBeginImageContext(area.size); 
CGContextRef context = UIGraphicsGetCurrentContext(); 
CGContextRetain(context); 

// mirroring context 
CGContextTranslateCTM(context, 0.0, area.size.height); 
CGContextScaleCTM(context, 1.0, -1.0); 

for (...) { 
    CGContextBeginTransparencyLayer(context, nil); 
    CGContextSetAlpha(context, alpha); 
    CGContextDrawImage(context, area, tempimg.CGImage); 
    CGContextEndTransparencyLayer(context); 
} 

// get created image 
UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
CGContextRelease(context); 
UIGraphicsEndImageContext(); 
+0

Vui lòng giải thích cách đây là cải tiến so với các câu trả lời trước đó/hoặc trong hoàn cảnh nào bạn sẽ sử dụng nó/hoặc tại sao giải pháp thay thế này có thể hữu ích. Cảm ơn. – ToolmakerSteve

89

Đây là những gì tôi đã làm trong ứng dụng của tôi, tương tự như Tyler - nhưng không có UIImageView:

UIImage *bottomImage = [UIImage imageNamed:@"bottom.png"]; 
UIImage *image = [UIImage imageNamed:@"top.png"]; 

CGSize newSize = CGSizeMake(width, height); 
UIGraphicsBeginImageContext(newSize); 

// Use existing opacity as is 
[bottomImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; 
// Apply supplied opacity 
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeNormal alpha:0.8]; 

UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 

UIGraphicsEndImageContext(); 

Nếu hình ảnh đã có opacity , bạn không cần phải đặt nó (như trong bottomImage) nếu không bạn có thể đặt nó (như với image).

+1

Cảm ơn bạn rất nhiều !!! Giải quyết một 6 giờ prblem! –

+0

Cảm ơn câu trả lời này ... Nó hoạt động giống như nét duyên dáng ... Nhưng tôi muốn làm tương tự cho hai lớp .... – Alfa

+3

Đối với hỗ trợ hiển thị võng mạc và không võng mạc, sử dụng 'UIGraphicsBeginImageContextWithOptions (newSize, NO, 0.0f); ', cho UIKit biết lấy và sử dụng hệ số tỷ lệ của màn hình chính của thiết bị. –

9

câu trả lời của tôi dựa trên Eric's answer, nhưng cho phép @ 2x hình ảnh giữ lại độ phân giải của chúng sau khi hợp nhất hình ảnh. Xin lưu ý URL REF trong các nhận xét của tôi, vì tôi thừa nhận các nguồn đã hỗ trợ cho sự phát triển của tôi về chức năng này mà tôi đã sử dụng trong các ứng dụng iOS của mình.

- (UIImage*) mergeTwoImages : (UIImage*) topImage : (UIImage*) bottomImage 
{ 
    // URL REF: http://iphoneincubator.com/blog/windows-views/image-processing-tricks 
    // URL REF: https://stackoverflow.com/questions/1309757/blend-two-uiimages?answertab=active#tab-top 
    // URL REF: http://www.waterworld.com.hk/en/blog/uigraphicsbeginimagecontext-and-retina-display 

    int width = bottomImage.size.width; 
    int height = bottomImage.size.height; 

    CGSize newSize = CGSizeMake(width, height); 
    static CGFloat scale = -1.0; 

    if (scale<0.0) 
    { 
     UIScreen *screen = [UIScreen mainScreen]; 

     if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 4.0) 
     { 
      scale = [screen scale]; 
     } 
     else 
     { 
      scale = 0.0; // Use the standard API 
     } 
    } 

    if (scale>0.0) 
    { 
     UIGraphicsBeginImageContextWithOptions(newSize, NO, scale); 
    } 
    else 
    { 
     UIGraphicsBeginImageContext(newSize); 
    } 

    [bottomImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; 
    [topImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeNormal alpha:1.0]; 

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return newImage; 
} 
2

Swift 3

Chức năng này sẽ mất hai hình ảnh, và một CGSize và trả về một tùy chọn UIImage. Nó hoạt động tốt nhất khi cả hai hình ảnh có cùng kích thước. Nếu hình ảnh trên cùng của bạn có alpha, nó sẽ hiển thị hình ảnh dưới cùng thông qua nó.

// composit two images 
func compositeTwoImages(top: UIImage, bottom: UIImage, newSize: CGSize) -> UIImage? { 
    // begin context with new size 
    UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0) 
    // draw images to context 
    bottom.draw(in: CGRect(origin: CGPoint.zero, size: newSize)) 
    top.draw(in: CGRect(origin: CGPoint.zero, size: newSize)) 
    // return the new image 
    let newImage = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 
    // returns an optional 
    return newImage 
} 

Cách sử dụng

let outputSize = CGSize(width: 100, height: 100) 
if let topImage = UIImage(named: "myTopImage") { 
    if let bottomImage = UIImage(named: "myBottomImage") { 
     // composite both images 
     if let finalImage = compositeTwoImages(top: topImage, bottom: bottomImage, newSize: outputSize) { 
      // do something with finalImage 
     } 
    } 
} 
Các vấn đề liên quan