2014-11-02 128 views
2

我有一個層,我希望用戶繪製一個'面具'剪切圖像。它是半透明的,所以他們可以看到他們正在選擇的東西下面。如何去除不透明度,但保持UIImage的alpha通道?

我該如何處理這個圖形數據,其alpha值爲1.0,但保留alpha通道(用於掩碼)?

TL:DR - 我想讓黑色區域成爲一種純色,單色。

  • 下面是之前和之後所希望的(白色背景應該在這兩個是透明的): Desired Before & After

是這樣的:

for (pixel in image) { 
    if (pixel.alpha != 0.0) { 
    fill solid black 
    } 
} 

回答

2

下應該做什麼你」重新過後。大部分代碼是從How to set the opacity/alpha of a UIImage?我只是在將像素的顏色轉換爲黑色之前,爲alpha值添加了一個測試。

// Create a pixel buffer in an easy to use format 
CGImageRef imageRef = [[UIImage imageNamed:@"testImage"] CGImage]; 
NSUInteger width = CGImageGetWidth(imageRef); 
NSUInteger height = CGImageGetHeight(imageRef); 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

UInt8 * m_PixelBuf = malloc(sizeof(UInt8) * height * width * 4); 

NSUInteger bytesPerPixel = 4; 
NSUInteger bytesPerRow = bytesPerPixel * width; 
NSUInteger bitsPerComponent = 8; 
CGContextRef context = CGBitmapContextCreate(m_PixelBuf, width, height, 
              bitsPerComponent, bytesPerRow, colorSpace, 
              kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 

CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); 
CGContextRelease(context); 

//alter the alpha when the alpha of the source != 0 
int length = height * width * 4; 
for (int i=0; i<length; i+=4) { 
    if (m_PixelBuf[i+3] != 0) { 
    m_PixelBuf[i+3] = 255; 
    } 
} 

//create a new image 
CGContextRef ctx = CGBitmapContextCreate(m_PixelBuf, width, height, 
             bitsPerComponent, bytesPerRow, colorSpace, 
             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 

CGImageRef newImgRef = CGBitmapContextCreateImage(ctx); 
CGColorSpaceRelease(colorSpace); 
CGContextRelease(ctx); 
free(m_PixelBuf); 

UIImage *finalImage = [UIImage imageWithCGImage:newImgRef]; 
CGImageRelease(newImgRef); 

finalImage現在將包含一個圖像,其中不具有的0.0的α的所有像素具有爲1

+0

不錯,只需要一個小的調整,使像素黑色: 'for(int i = 0; i Halpo 2014-11-03 07:36:55

+0

有了所有適當的推理,我不認爲這種調整原始位圖的像素緩衝區的技術是正確的方法。這假設alpha通道簡單地反映了線路的不透明性。但是您渲染的路徑可能具有消除鋸齒的邊緣;這種技術將不必要地在面具中引入鋸齒。我建議不要像這樣編輯像素緩衝區。相反,您想要使用1.0的alpha值重新渲染模型的原始路徑。這樣,您的面罩將享受邊緣的抗鋸齒性質,同時使主要行程路徑完全不透明。 – Rob 2014-11-03 14:57:46

1

基礎模型阿爾法此應用不應圖像。這不是一個「如何從另一個圖像創建一個圖像再現」的問題。

相反,底層對象模型應該是一個路徑數組。然後,當你想創建具有半透明路徑與不透明路徑的圖像時,這只是你如何呈現這個路徑數組的問題。一旦你解決這個問題,這個問題不是一個複雜的圖像處理問題,而是一個簡單的渲染問題。

順便說一下,我真的很喜歡這個路徑數組模型,因爲這樣做會變得相當的微不足道,例如「gee,讓我提供一個撤銷函數,讓用戶一次刪除一個筆畫。它爲您打開各種不錯的功能增強。

就如何呈現這些路徑的具體細節而言,它可以以各種不同的方式實現。您可以使用自定義drawRect函數來呈現具有適當字母的路徑的UIView子類。或者您也可以使用CAShapeLayer對象。或者你可以做一些混合(當你完成添加每個路徑時創建新的圖像快照,避免每次重新渲染所有路徑)。有很多方法可以解決這個問題。

但關鍵的洞察力是採用的路徑的數組的底層模型,然後將兩種圖像的渲染變得相當簡單的練習:

pathsmask

第一個圖像是渲染一組路徑爲CAShapeLayer對象,其中alpha爲0.5。第二個是相同的渲染,但是具有1.0的alpha。同樣,如果使用形狀圖層或低級別的Core Graphics調用,則無關緊要,但其基本思路是相同的。使用半透明渲染你的路徑。

+0

我的應用程序使用路徑(與撤消能力等),這只是一個最終的渲染解決方案 – Halpo 2014-11-03 07:38:29

+0

然後我不明白這個問題。兩次渲染你的路徑以得到兩幅圖像,一次用alpha少於一次,然後再用alpha等於一。這會產生你需要的兩個圖像。 – Rob 2014-11-03 13:24:30

相關問題