Страницы

Поиск по вопросам

среда, 13 марта 2019 г.

Преобразовать массив пикселей в изображение в ios

Доброго времени суток коллеги! У меня похоже не правильно работает эта функция. Мне нужно:
Cоздать массив. Установить массив в качестве изображения
Я написал примерно такую реализацию:
//функция создаёт массив пикселей - (void)ProccessImage { //352*288*4 = РАЗМЕР КАРТИНКИ
unsigned char * buf = (unsigned char*)malloc(352*288*4);//выделить память под массив unsigned int *ibuf = (unsigned int *)buf; //
for(int i = 0; i<352*288*4; i++){ //заполняем массив пикселей ibuf[i] = i|0x80808080; } UIImage*imageFromArray = [self convertBitmapRGBA8ToUIImage:buf withWidth:352 withHeight:288]; //создание изображения из массива пикселей. [ChangeImageView setImage:imageFromArray]; //установка изображения в ImageView
free(buf); }
/*Функция по конвертации массива unsigned сhar в картинку. Дёрнута отсюда https://stackoverflow.com/questions/7650144/how-to-convert-bytearray-to-image-in-objective-c */ - (UIImage *) convertBitmapRGBA8ToUIImage:(unsigned char *) buffer withWidth:(int) width withHeight:(int) height {
size_t bufferLength = width * height * 4; CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, bufferLength, NULL); size_t bitsPerComponent = 8; size_t bitsPerPixel = 32; size_t bytesPerRow = 4 * width;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); if(colorSpaceRef == NULL) { NSLog(@"Error allocating color space"); CGDataProviderRelease(provider); return nil; }
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast; CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef iref = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, // data provider NULL, // decode YES, // should interpolate renderingIntent);
uint32_t* pixels = (uint32_t*)malloc(bufferLength);
if(pixels == NULL) { NSLog(@"Error: Memory not allocated for bitmap"); CGDataProviderRelease(provider); CGColorSpaceRelease(colorSpaceRef); CGImageRelease(iref); return nil; } // memcpy(pixels,buffer,bufferLength); CGContextRef context = CGBitmapContextCreate(pixels, width, height, bitsPerComponent, bytesPerRow, colorSpaceRef, bitmapInfo);
if(context == NULL) { NSLog(@"Error context not created"); free(pixels); }
UIImage *image = nil; if(context) {
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), iref);
CGImageRef imageRef = CGBitmapContextCreateImage(context);
// Support both iPad 3.2 and iPhone 4 Retina displays with the correct scale if([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) { float scale = [[UIScreen mainScreen] scale]; image = [UIImage imageWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp]; } else { image = [UIImage imageWithCGImage:imageRef]; }
CGImageRelease(imageRef); CGContextRelease(context); }
CGColorSpaceRelease(colorSpaceRef); CGImageRelease(iref); CGDataProviderRelease(provider);
if(pixels) { free(pixels); } return image; } //Конец функции по конвертации массива в изображение
В результате вышеуказанной реализации, устанавливается в imageView белый экран.
Вопрос: Как изменить реализацию так, чтобы в imageView был заполнен разноцветными точками (чем-нибудь отличающимся от белого цвета)?


Ответ

Вот этот код генерирует мне картинку шума, если его вставить, например, во viewDidLoad
int width = 500; int height = 500;
size_t bufferLength = width * height * 4; uint8_t* pixels = (uint8_t*)malloc(bufferLength); for (int i = 0; i < bufferLength; i++) { pixels[i] = rand() % 255; }
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(pixels, width, height, 8, width * 4, space, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast);
CGImageRef toCGImage = CGBitmapContextCreateImage(ctx); UIImage * uiimage = [[UIImage alloc] initWithCGImage:toCGImage];
CGImageRelease(toCGImage); CGColorSpaceRelease(space); CGContextRelease(ctx); free(pixels); UIImageView *imageView = [[UIImageView alloc] initWithImage:uiimage]; [self.view addSubview:imageView];
Для заполнения массива чем-то конкретным
Есть формат пикселя, который определяется параметром kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast. Это значит RGBA, то есть каждый пиксель состоит из 4-х байтов, последовательно - красный (Red), зелёный (Green), синий (Blue), альфа (прозрачность). То есть, для установки конкретного массива пикселей, нужно забивать массив последовательностью из 4-х байт, последний из которых - 255 (то есть без прозрачности). Например:
for (int i = 0; i < width * height; i++) { pixels[i * 4] = 100; //баланс красного pixels[i * 4 + 1] = 200; //баланс зеленого pixels[i * 4 + 2] = 50; //баланс синего pixels[i * 4 +3] = 255; //прозрачности }

Комментариев нет:

Отправить комментарий