2012-03-13 76 views
2

我有一個NSData對象,其中包含圖像的RGB值。我想把它變成一個UIImage(給定的寬度和高度)。然後我想將該UIImage轉換回與我開始使用的對象相同的NSData對象。NSData - > UIImage - > NSData

請幫幫我我一直在嘗試幾個小時。

這裏有一些事情我已經看了/試過雖然可能沒有太多他們的權利,因爲它沒有工作:

CGImageCreate 
CGBitmapContextCreateWithData 
CGBitmapContextGetData 
CGDataProviderCopyData(CGImageGetDataProvider(imageRef)) 

謝謝!

這裏是我當前的代碼:

NSMutableData *rgb; //made earlier 
double len = (double)[rgb length]; 
len /= 3; 
len += 0.5; 
len = (int)len; 
int diff = len*3-[rgb length]; 
NSString *str = @"a"; 
NSData *a = [str dataUsingEncoding:NSUTF8StringEncoding]; 
for(int i =0; i < diff; i++) { 
    [toEncode appendData:a]; //so if my data is RGBRGBR it will turn into RGBRGBR(97)(97) 
} 
size_t width = (size_t)len; 
size_t height = 1; 
CGContextRef ctx; 
CFDataRef m_DataRef; 
m_DataRef = (__bridge CFDataRef)toEncode; 
UInt8 * m_PixelBuf = (UInt8 *) CFDataGetBytePtr(m_DataRef); 
vImage_Buffer src; 
src.data = m_PixelBuf; 
src.width = width; 
src.height = height; 
src.rowBytes = 3 * width; 
vImage_Buffer dst; 
dst.width = width; 
dst.height = height; 
dst.rowBytes = 4 * width; 
vImageConvert_RGB888toARGB8888(&src, NULL, 0, &dst, NO, kvImageNoFlags); 
// free(m_PixelBuf); 
// m_PixelBuf = dst.data; 
// NSUInteger lenB = len * (4/3); 
/* 
UInt8 * m_Pixel = malloc(sizeof(UInt8) * lenB); 
int z = 0; 
for(int i = 0; i < lenB; i++) { 
if(i % 4==0) { 
m_Pixel[i] = 0; 
} else { 
m_Pixel[i] = m_PixelBuf[z]; 
z++;    
} 
}*/ 
// Byte tmpByte; 

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
/* 
ctx = CGBitmapContextCreate(m_PixelBuf, 
width, 
height, 
8, 
4*width, 
colorSpace, 
kCGImageAlphaPremultipliedFirst); 
*/ 
size_t w = (size_t)len; 
ctx = CGBitmapContextCreate(dst.data, 
          w, 
          height, 
          8, 
          4*width, 
          colorSpace, 
          kCGImageAlphaNoneSkipFirst);  
CGImageRef imageRef = CGBitmapContextCreateImage (ctx); 
UIImage* rawImage = [UIImage imageWithCGImage:imageRef]; 

CGContextRelease(ctx); 

我得到這個錯誤:<Error>: CGBitmapContextCreate: invalid data bytes/row: should be at least 324 for 8 integer bits/component, 3 components, kCGImageAlphaNoneSkipFirst.

+2

更詳細地描述你的輸入'NSData'格式。向我們展示您嘗試的*實際*代碼,而不是模糊地描述它。 – 2012-03-13 19:51:21

+0

這個格式就是:R,G,B,R,G,B,R,G,B ...... 因此,例如我想創建一個100像素×100像素的圖像: 100 * 100 *存儲在nsdata對象中的3個字節。 – user924387 2012-03-13 20:48:19

+0

您還需要編輯您的問題並粘貼您的實際代碼。 – 2012-03-13 20:58:07

回答

5

從NSData的UIImage的:

[UIImage imageWithData:] 

更多關於UIImage

TO的NSData從UIImage的:

UIImage *img = [UIImage imageNamed:@"some.png"]; 
NSData *dataObj = UIImageJPEGRepresentation(img, 1.0); 

更多關於UIImageJPEGRepresentation()

+1

這隻適用於已經處於某種標準(最可能壓縮的)圖像格式(png,jpg ...)的數據,但不適用於原始像素數據。 – omz 2012-03-13 19:57:29

+0

提示@omz Thnx。 – Jeremy 2012-03-13 19:58:10

2

的基本過程將是使用CGBitmapContextCreateWithData,然後用CGBitmapContextCreateImage創建從一個CGImageRef創建位圖上下文。用於創建位圖上下文的參數取決於您的原始數據在內存中的佈局。 Quartz不支持所有類型的原始數據。

documentation on CGBitmapContextCreateWithData是非常詳細,這是最具挑戰性的部分,正從上下文和包裹的CGImageRef,在一個UIImageimageWithCGImage:)是微不足道的事後。

+0

我可以在3通道圖像上使用CGBitmapContextCreate嗎?我的數據是RGB而不是RGBA格式 – user924387 2012-03-13 20:24:47

+0

實際上,我怎樣纔能有效地爲我的數據添加一個空的alpha通道?例如,如果我的數據當前是:R,G,B,R,G,B,R,G,B將它變成0,R,G,B,0,R,G,B,0,R, G,B – user924387 2012-03-13 20:49:27

+1

您可以使用Accelerate框架中的'vImageConvert_RGB888toARGB8888'功能創建包含Alpha通道的圖像數據副本。 [文檔](https://developer.apple.com/library/ios/#documentation/Performance/Reference/vImage_conversion/Reference/reference.html) – 2012-03-13 20:56:03

0

如果您的數據爲RGB格式,則需要使用CGBitmapContextCreateCGColorSpaceCreateDeviceRGB並使用kCGImageAlphaNone來創建位圖。

+0

我試過了,我得到CGBitmapContextCreate:不支持的參數組合:8個整數位/分量; 24位/像素; 3分量色彩空間; kCGImageAlphaNone; – user924387 2012-03-13 21:12:15

+0

對啊。然後使用alpha創建位圖,但只需跳過設置/讀取alpha值即可。 – 2012-03-13 21:17:58

+0

所以你的意思是像kCGImageAlphaNoneSkipFirst?現在我正在嘗試@rob mayoff建議在Accelerate框架中使用vImageConvert_RGB888toARGB8888函數 – user924387 2012-03-13 21:28:53

0

錯誤,指出rowBytes至少需要324;除以4即爲81,這意味着'寬度'小於'w',並且w = 81。這兩個值應該匹配。

試着用一個像5這樣的小數字代替寬度和w來驗證這一點。我還會注意到,在調用vImageConvert_RGB888toARGB8888之前,您應該通過malloc分配dst.data。

考慮使用CGImageCreate(),而不是創建一個bitmapcontext:

// this will automatically free() dst.data when destData is dealloc 
NSData *destData = [NSData dataWithBytesNoCopy:dst.data length:4*width*height]; 
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)destData); 
CGImageRef imageRef = CGImageCreate(width, 
            height, 
            8,       //bits per component 
            8*4,      //bits per pixel 
            4*width,     //bytesPerRow 
            colorSpace,     //colorspace 
            kCGImageAlphaNoneSkipFirst, 
            provider,     //CGDataProviderRef 
            NULL,      //decode 
            false,      //should interpolate 
            kCGRenderingIntentDefault //intent 
            ); 
相關問題