2009-07-15 88 views
10

我有這段代碼來掩蓋圖像。基本上,我只使用PNG圖像。所以我有一個24位色彩(PNG-24)的300x400 PNG圖像。我不確定它是否也有alpha通道。但它沒有透明度。任何想法爲什麼這個圖像掩碼不起作用?

然後,存在圖像掩模是PNG-8位無alpha通道。它只是黑色,灰度和白色。

我創建這兩個圖像作爲UIImage的。將它們放入UIImageView時都可以正確顯示。

然後,我創建的UIImage了出來其中包含屏蔽操作的結果,使用此代碼:

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

這裏就是我做的是:

UIImage *image = [UIImage imageNamed:@"coloredImagePNG24.png"]; 
UIImage *maskImage = [UIImage imageNamed:@"theMaskPNG8_Grayscale_NoAlpha.png"]; 
UIImage *maskedImage = [MyGraphicUtils maskImage:image withMask:maskImage]; 
UIImageView *testImageView = [[UIImageView alloc] initWithImage:maskedImage]; 
testImageView.backgroundColor = [UIColor clearColor]; 
testImageView.opaque = NO; 

畢竟是, coloredImagePNG24.png保持完好無損。沒有掩蔽正在發生。但現在奇怪的是:如果我把周圍的,即使用這個形象的面具,面具的彩色圖像到面膜,然後我得到的東西在灰度非常難看(但屏蔽;))。

任何想法有什麼錯我的代碼?

更新:我只是用Google搜索的不同的B/W巴紐使用它作爲一個面具。然後這個工作!但是我自己做的那個不起作用。所以我認爲代碼有很大的圖像解碼問題。我將不得不將圖像「歸一化」爲特定的格式,以便它能夠正常工作。

回答

0

看它是否適用於任何這樣更好:

+ (UIImage*)maskImage:(UIImage*)image withMask:(UIImage*)maskImage { 
    UIGraphicsBeginImageContext(image.size); 
    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); 
    UIImage* result = [UIImage imageWithData:UIImagePNGRepresentation(UIGraphicsGetImageFromCurrentImageContext())]; 
    UIGraphicsEndImageContext(); 
    CGImageRelease(mask); 
    CGImageRelease(masked); 
    return result; 
} 
+1

雖然看起來很漂亮,在我的情況它只是使圖像完全透明。看到我上面的更新。我想出了一些奇怪的東西。 – Thanks 2009-07-15 20:07:37

+1

我在上面的代碼中使用了一個變體,將在Photoshop中創建的蒙版轉換爲「灰度」並導出爲24位PNG。 – Ramin 2009-07-15 22:44:42

+0

如果您想使用上面的代碼,請確保包含該掩碼的圖像文件是不具有Alpha通道的24位PNG。例如,Pixelmator不會告訴你這些信息。你需要使用Photoshop或Gimp。 – 2014-05-06 05:42:53

0

戴夫,我聽說有一個Alpha通道的PNG圖片,可以影響這種代碼。

我只是一派PNG Alpha通道以及與此鏈接想出了:link text

因此,請確保您使用的PNG有一個正確地設置Alpha通道

3

CGImageMaskCreate做什麼你的期望。特別是:

對於圖像掩模是每個組件2,4,或8位,每個組件通過使用該式縮放映射到範圍從0到1:

1 /(2 ^每個分量的比特 - 1)

例如,一個4位的掩模具有範圍從0到15這些值由1/15換算值,使得每個成分範圍從0到1的元件值即重新縮放0或1的行爲方式與1位圖像掩模的行爲相同。縮放到0到1之間的值作爲逆阿爾法。也就是說,填充顏色被繪製爲具有(1 - MaskSampleValue)的alpha值。例如,如果8位掩碼的採樣值縮放到0.8,則當前填充顏色被繪製爲具有0.2的α值,即(1-0.8)。

我的猜測是該功能是重新解釋您的RGB數據在這種不同的格式,這扭曲了顏色值。你有沒有嘗試過直接使用mask CGImage?

快速編輯:我所說的意思是「直接」只是寫

+ (UIImage*)maskImage:(UIImage*)image withMask:(UIImage*)maskImage 
{ 
    CGImageRef masked = CGImageCreateWithMask([image CGImage], [maskImage CGImage]); 
    return [UIImage imageWithCGImage:masked]; 
} 
5

當你發現,你如何保存文件可以有所作爲,因爲核芯顯卡是非常講究的格式它用於掩蔽的位。

我發現,產生從任意圖像的圖像面膜最好的和最可靠的方法是做到這一點:

  1. 創建在圖像掩碼可以接受的格式的位圖圖形上下文(您不能使用UIGraphicsBeginImageContext()爲此)
  2. 將您的圖像繪製到此位圖圖形上下文
  3. 從位圖圖形上下文位創建圖像蒙版。

試試這個功能:

CGImageRef createMaskWithImage(CGImageRef image) 
{ 
    int maskWidth    = CGImageGetWidth(image); 
    int maskHeight    = CGImageGetHeight(image); 
    // round bytesPerRow to the nearest 16 bytes, for performance's sake 
    int bytesPerRow    = (maskWidth + 15) & 0xfffffff0; 
    int bufferSize    = bytesPerRow * maskHeight; 

    // allocate memory for the bits 
    CFMutableDataRef dataBuffer = CFDataCreateMutable(kCFAllocatorDefault, 0); 
    CFDataSetLength(dataBuffer, bufferSize); 

    // the data will be 8 bits per pixel, no alpha 
    CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceGray(); 
    CGContextRef ctx   = CGBitmapContextCreate(CFDataGetMutableBytePtr(dataBuffer), 
                 maskWidth, maskHeight, 
                 8, bytesPerRow, colourSpace, kCGImageAlphaNone); 
    // drawing into this context will draw into the dataBuffer. 
    CGContextDrawImage(ctx, CGRectMake(0, 0, maskWidth, maskHeight), image); 
    CGContextRelease(ctx); 

    // now make a mask from the data. 
    CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData(dataBuffer); 
    CGImageRef mask     = CGImageMaskCreate(maskWidth, maskHeight, 8, 8, bytesPerRow, 
                 dataProvider, NULL, FALSE); 

    CGDataProviderRelease(dataProvider); 
    CGColorSpaceRelease(colourSpace); 
    CFRelease(dataBuffer); 

    return mask; 
} 
-6

您不能創建一個圖像,任何種類的,具有核心圖形不具有一個alpha通道。

6

此代碼可以幫助你

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

} 

請參閱本example demonstration

1

的下面幾行代碼爲我工作

+(UIImage*)maskImageExt:(UIImage *)image withMask:(UIImage *)maskImage { 
     CGImageRef maskRef = maskImage.CGImage; 
     CGImageRef imageRef = image.CGImage; 

     CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef), 
            CGImageGetHeight(maskRef), 
            CGImageGetBitsPerComponent(maskRef), 
            CGImageGetBitsPerPixel(maskRef), 
            CGImageGetBytesPerRow(maskRef), 
            CGImageGetDataProvider(maskRef), NULL, true); 

CGImageRef maskImageRef = CGImageCreateWithMask([image CGImage], mask); 

CGContextRef context = CGBitmapContextCreate(nil, 
              CGImageGetWidth(imageRef), 
              CGImageGetHeight(imageRef), 
              CGImageGetBitsPerComponent(imageRef), 
              CGImageGetBytesPerRow(imageRef), 
              CGImageGetColorSpace(imageRef), 
              CGImageGetBitmapInfo(imageRef)); 
CGRect imageRect = CGRectMake(0, 0, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); 
CGContextDrawImage(context, imageRect, maskImageRef); 
CGImageRef maskedImageRef = CGBitmapContextCreateImage(context); 
UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef]; 

CGImageRelease(mask); 
CGContextRelease(context); 
CGImageRelease(maskedImageRef); 

return maskedImage; 

}

相關問題