Страницы

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

четверг, 23 января 2020 г.

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

#массивы #ios #objective_c #обработка_изображений


Доброго времени суток коллеги! У меня похоже не правильно работает эта функция. Мне
нужно:


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 был заполнен разноцветными
точками (чем-нибудь отличающимся от белого цвета)? 
    


Ответы

Ответ 1



Вот этот код генерирует мне картинку шума, если его вставить, например, во 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; //прозрачности }

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

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