简体   繁体   English

NSData-> UIImage-> NSData

[英]NSData -> UIImage -> NSData

I have an NSData object, which contains RGB values for an image. 我有一个NSData对象,其中包含图像的RGB值。 I want to turn that into a UIImage (given the width and the height). 我想把它变成一个UIImage (给定宽度和高度)。 Then I want to convert that UIImage back into an NSData object identical to the one I started with. 然后,我想将该UIImage转换回与我最初使用的对象相同的NSData对象。

Please help me I've been trying for hours now. 请帮助我,我已经尝试了几个小时。

Here are some things I've looked at/tried though probably didn't too them right cause it didn't work: 这是我已经查看/尝试过的一些内容,尽管可能不太正确,因为它不起作用:

CGImageCreate
CGBitmapContextCreateWithData
CGBitmapContextGetData
CGDataProviderCopyData(CGImageGetDataProvider(imageRef))

Thanks! 谢谢!

Here is my current code: 这是我目前的代码:

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); 

I get this error: <Error>: CGBitmapContextCreate: invalid data bytes/row: should be at least 324 for 8 integer bits/component, 3 components, kCGImageAlphaNoneSkipFirst. 我收到此错误: <Error>: CGBitmapContextCreate: invalid data bytes/row: should be at least 324 for 8 integer bits/component, 3 components, kCGImageAlphaNoneSkipFirst.

TO UIImage from NSData: 从NSData到UIImage:

[UIImage imageWithData:]

More on UIImage 有关UIImage的更多信息

TO NSData from UIImage: 从UIImage到NSData:

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

More on UIImageJPEGRepresentation() 有关UIImageJPEGRepresentation()的更多信息

The basic procedure would be to create a bitmap context using CGBitmapContextCreateWithData and then creating a CGImageRef from that with CGBitmapContextCreateImage . 基本程序是使用创建位图背景CGBitmapContextCreateWithData然后创建一个CGImageRef从与CGBitmapContextCreateImage The parameters for creating the bitmap context depend on how your raw data is laid out in memory. 用于创建位图上下文的参数取决于原始数据在内存中的布局方式。 Not all kinds of raw data are supported by Quartz. Quartz并不支持所有类型的原始数据。

The documentation on CGBitmapContextCreateWithData is quite detailed, and this is the most challenging part, getting the CGImageRef from the context and wrapping that in a UIImage ( imageWithCGImage: ) is trivial afterwards. CGBitmapContextCreateWithData文档非常详细,这是最具挑战性的部分,从上下文中获取CGImageRef并将其包装在UIImageimageWithCGImage:是很简单的。

The error stating that rowBytes needs to be at least 324; 错误消息指出rowBytes必须至少为324; dividing that by 4 is 81 which implies that 'width' is smaller than 'w', and that w=81. 将其除以4是81,这意味着“宽度”小于“ w”,并且w = 81。 The two values should match. 这两个值应该匹配。

Try replacing width and w with a small number like 5 to validate this. 尝试用较小的数字(例如5)替换width和w来验证这一点。 I would also note that you should be allocating dst.data via malloc prior to calling vImageConvert_RGB888toARGB8888. 我还要指出,在调用vImageConvert_RGB888toARGB8888之前,您应该通过malloc分配dst.data。

Consider using CGImageCreate() instead of creating a bitmapcontext: 考虑使用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
                                    );

如果您的数据是RGB格式,则需要使用CGBitmapContextCreateCGColorSpaceCreateDeviceRGB并使用kCGImageAlphaNone创建位图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM