【问题标题】:How to convert bytearray to image in Objective-C如何在 Objective-C 中将字节数组转换为图像
【发布时间】:2017-08-22 18:58:58
【问题描述】:

就是这样
我有一个指向 BMP 图像数据的无符号字符指针
在我用指针循环后,我实现了一个包含 int 值 0 - 255 的字节数组

我想要的是将数组中的这个值转换为 BMP 图像 在 UIImage 中显示。

**图片为灰度图

【问题讨论】:

  • 所以它是 BMP 格式文件的内存映像,或者您只是更一般地表示“BMP”以便您拥有,例如100 字节代表 10x10 灰度图像?

标签: objective-c uiimage bytearray


【解决方案1】:

我会想象这样的事情。未经测试,所以准备好调整:)

UIImage *yourImage = [UIImage imageWithData: [NSData dataWithBytes: yourCharPointer length : sizeof(yourCharPointer)]];

【讨论】:

  • 首先,基于这个问题,听起来图像数据只是一个像素值数组,所以 imageWithData 不知道如何处理它。必须将 BMP 文件头添加到图像数据中。其次, sizeof(yourCharPointer) 会根据 CPU 产生 4 或 8。
  • 顺便说一下@Patrick Perini,您的代码不需要测试它可以按原样工作;)
【解决方案2】:

这个代码sn-p来自这个blog,我建议你看看那里和project site in Github

另请注意,此类方法适用于 RGB8 图像,因此您需要在 bitsPerPixel(灰度应为 8)、bytesPerRow(1 * 宽度)、bufferLength(删除 * 4)并使用 CGColorCreateGenericGray 创建 colorSpaceRef

我还注意到,使用 CGColorCreateGenericGray 创建色彩空间假设您的数组具有 alpha 信息。所以也许你应该为每个像素添加一个 alpha 字节以使其正常工作。

+ (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;
    }

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

【讨论】:

  • 2011-10-05 04:26:04.273 Sample[1481:6603] BMP Oct 5 04:26:04 macs-iPad Sample[1481] : CGBitmapContextCreate: 不支持的参数组合: 8整数位/分量; 24 位/像素;三分量色彩空间; kCGImageAlphaNone; 350 字节/行。 10 月 5 日 04:26:04 macs-iPad Sample[1481] : CGBitmapContextCreateImage: invalid context 0x0
  • 谢谢你的回答非常好,但有一件事我不知道为什么图像出现偏移
【解决方案3】:

由于接受的答案太长,我写了另一个解决方案:

- (UIImage*) imageFromArray:(const char*)pixelArray width:(int)width height:(int)height {

    int imageSizeInPixels = width * height;
    int bytesPerPixel = 2; // 1 byte for brightness, 1 byte for alpha
    unsigned char *pixels = (unsigned char *)malloc(imageSizeInPixels * bytesPerPixel);
    memset(pixels, 255, imageSizeInPixels * bytesPerPixel); // setting alpha values to 255
    for (int i = 0; i < imageSizeInPixels; i++) {
        pixels[i * 2] = pixelArray[i]; // writing array of bytes as image brightnesses
    }

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pixels, imageSizeInPixels * bytesPerPixel, NULL);
    CGImageRef cgImage = CGImageCreate(width, height, 8, 8 * bytesPerPixel, width * bytesPerPixel, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big, provider, NULL, false, kCGRenderingIntentDefault);
    UIImage *image = [UIImage imageWithCGImage:cgImage];

    return image;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    相关资源
    最近更新 更多