2013-10-05 139 views
0

我想在iOS中的兩張圖片之間做一個選擇性的遮罩,類似於Blender中的遮罩功能。有兩個圖像1和2(調整大小相同的尺寸)。最初只有圖像1可見,但無論用戶觸摸image1上的任何區域,它都變得透明,圖像2在這些區域中變得可見。掩蔽兩張圖片

我用觸摸移動使用核心圖形創建了一個面具般的圖像。它基本上是一個全黑的圖像,無論我在哪裏觸摸,都會有白色部分。整個alpha設置爲1.0。我可以使用這個圖像作爲蒙版,並通過實現我自己的圖像處理方法來完成必要的操作,這些方法將遍歷每個像素,檢查並根據值進行設置。現在這種方法將被稱爲內部觸摸移動,所以我的方法可能會減慢整個過程(特別是對於800萬像素的相機圖像)。

我想知道如何通過使用Quartz Core或Core Graphics來實現這個功能,這樣可以高效運行大圖片。

代碼我迄今爲止:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    mouseSwiped = YES; 

    UITouch *touch = [touches anyObject]; 
    CGPoint currentPoint = [touch locationInView:staticBG]; 

    UIGraphicsBeginImageContext(staticBG.frame.size); 
    [maskView.image drawInRect:CGRectMake(0, 0, maskView.frame.size.width, maskView.frame.size.height)]; 

    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); 
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 20.0); 
    CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 1.0, 1.0, 0.0); 
    CGContextBeginPath(UIGraphicsGetCurrentContext()); 
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y); 
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y); 
    CGContextStrokePath(UIGraphicsGetCurrentContext()); 

    maskView.image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    lastPoint = currentPoint; 
    mouseMoved++; 
    if (mouseMoved == 10) 
     mouseMoved = 0; 

    staticBG.image = [self maskImage:staticBG.image withMask:maskView.image]; 
    //maskView.hidden = NO; 
} 

- (UIImage*) maskImage:(UIImage *)baseImage withMask:(UIImage *)maskImage 
{ 
    CGImageRef imgRef = [baseImage CGImage]; 
    CGImageRef maskRef = [maskImage CGImage]; 
    CGImageRef actualMask = CGImageMaskCreate(CGImageGetWidth(maskRef), 
              CGImageGetHeight(maskRef), 
              CGImageGetBitsPerComponent(maskRef), 
              CGImageGetBitsPerPixel(maskRef), 
              CGImageGetBytesPerRow(maskRef), 
              CGImageGetDataProvider(maskRef), NULL, false); 
    CGImageRef masked = CGImageCreateWithMask(imgRef, actualMask); 
    return [UIImage imageWithCGImage:masked]; 
} 

的maskImage方法不工作,因爲它創造根據α值的掩模圖像。 我經歷了這個鏈接:Creating Mask from Path但我無法理解答案。

回答

0

首先我會提到一些我希望你已經知道的東西。

  • 通過僅採用alpha值進行遮罩工作。
  • 在每次觸摸時創建一個具有核心圖形的圖像移動是一個相當大的開銷&你應該儘量避免或使用其他方式做事。
  • 嘗試使用靜態蒙版圖像。

我想建議你從顛倒的角度來看待這個問題。

ie不是試圖在頂部圖像中試圖查看底部的洞,爲什麼不把底部圖像放在頂部&掩蓋底部圖像,以便它能夠顯示用戶的觸摸點覆蓋特定頂部視圖部分。 ?

我做給你拿個主意在這裏>http://goo.gl/Zlu31T

好運&不要回來後如果有什麼不明確的例子。我相信雖然這樣做有更好的和優化的方式。 「_」

+0

雅您的實現是實時的速度不夠快,但你能不能給我任何想法,關於拯救的道路,我的意思是想我從中間開始並沿對角線頂端,然後我想通過整個路徑看到蘋果標誌圖像,而不是觸摸點周圍的特定圓圈。 – Soumyajit

+0

我讓我的查詢在這裏更清晰:http://stackoverflow.com/questions/19218422/rgbstroke-image-pixels-instead-of-color-ios 請看看.. – Soumyajit

+0

當你從你的圖像CGPath,設置爲遮罩層的內容屬性,就像我在示例中所做的一樣。 'masklayer.contents =(__bridge id)(imagefromCGPath.CGImage); bottomimage.layer.mask = masklayer; ' 要檢查性能,您必須在真實設備上運行此功能。請記住,模擬器上的CPU操作運行速度更快,而模擬器上GPU運行速度非常慢,因爲模擬器必須創建基於GPU的軟件代碼,所以GPU操作在真實設備上運行得更快。 – nsuinteger

0

由於您正在實時進行此操作,因此我建議您在編輯時假裝它,如果稍後需要輸出圖像,則可以將其掩蓋爲真實,因爲這可能需要一些時間(沒有太多,只是沒有足夠的速度來實時進行)。通過僞裝我的意思是把image1作爲背景,並在其上放置隱藏的圖像2。用戶觸摸該點後,將image2 UIImageView的邊界設置爲 CGRect rect= CGRectMake(touch.x - desiredRect.size.width/2, touch.y - desiredRect.size.height/2, desiredRect.size.width, desiredRect.size.height); 並使其可見。 desiredRect將是您想要顯示的image2的一部分。擡起手指後,您可以隱藏image2 UIImageView,以便image1完全可見。如果你的目標不是在當時輸出圖像,這是我現在能想到的最快的方式。

+0

這種方法看起來很有趣。我會嘗試一下並回復你。 有趣的是,許多應用程序都具有這種用戶驅動的遮罩功能,我認爲可能有一些直接的方式(或者人們正在通過openGL着色器實時進行) – Soumyajit

+0

這裏同樣的事情,也許我的問題並不完全清楚,但我想要對圖像本身進行永久更改,如果繪製路徑,則後圖像將在整個路徑中可見。如果我用我的手指摩擦整個imageView,那麼前面的圖像應該完全消失,背部圖像完全可見。 – Soumyajit

+0

http://stackoverflow.com/questions/19218422/rgbstroke-image-pixels-instead-of-color-ios – Soumyajit

0

使用此代碼,這將有助於掩蓋兩個UIImages

CGSize newSize = CGSizeMake(320, 377); 
       UIGraphicsBeginImageContext(newSize); 

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

      UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 

      UIGraphicsEndImageContext(); 

      imageData = UIImagePNGRepresentation(newImage); 
+0

我試過這個方法有點改變blendMode:kCGBlendModeColorMultiply仍然需要很多時間 – Soumyajit