NSData -> UIImage -> NSData - PullRequest
       2

NSData -> UIImage -> NSData

2 голосов
/ 13 марта 2012

У меня есть NSData объект, который содержит значения RGB для изображения. Я хочу превратить это в UIImage (учитывая ширину и высоту). Затем я хочу преобразовать этот 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.

Ответы [ 4 ]

5 голосов
/ 13 марта 2012

TO UIImage от NSData:

[UIImage imageWithData:]

Подробнее о UIImage

TO NSData из UIImage:

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

Подробнее о UIImageJPEGRepresentation ()

2 голосов
/ 13 марта 2012

Основной процедурой будет создание растрового контекста с использованием CGBitmapContextCreateWithData, а затем создание CGImageRef из этого с помощью CGBitmapContextCreateImage.Параметры для создания растрового контекста зависят от того, как ваши необработанные данные размещаются в памяти.Не все виды необработанных данных поддерживаются Quartz.

Документация по CGBitmapContextCreateWithData довольно подробная, и это самая сложная часть, получение CGImageRef из контекста изавершение этого в UIImage (imageWithCGImage:) впоследствии тривиально.

0 голосов
/ 14 апреля 2013

Ошибка, указывающая, что rowBytes должно быть не менее 324;деление на 4 равно 81, что означает, что «ширина» меньше, чем «w», и что w = 81.Два значения должны совпадать.

Попробуйте заменить ширину и w на небольшое число, например 5, чтобы подтвердить это.Я также хотел бы отметить, что вы должны распределять dst.data через malloc перед вызовом vImageConvert_RGB888toARGB8888.

Рассмотрите возможность использования CGImageCreate () вместо создания битового контекста:

// 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
                                    );
0 голосов
/ 14 марта 2012

Если ваши данные в формате RGB, вам нужно создать растровое изображение, используя CGBitmapContextCreate с CGColorSpaceCreateDeviceRGB и kCGImageAlphaNone.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...