将UIImage转换为uint8数组:iOS

时间:2014-06-29 18:23:37

标签: ios uiimage bytearray aes

我们可以将UIImage转换为uint8字节数组吗?

我在这里尝试做的是 - 我有一个图像,我想转换为8位字节数组。我还需要这个用于AES 256加密。

实际上我对这部分iOS完全不熟悉,所以需要基本的帮助。

1 个答案:

答案 0 :(得分:1)

这显示了如何根据原始图像访问图像并创建新图像(在这种情况下为半尺寸):

- (UIImage*) halveImage:(UIImage*)sourceImage {

    // Compute the target size
    CGSize sourceSize = sourceImage.size;
    CGSize targetSize;
    targetSize.width = (int) (sourceSize.width / 2);
    targetSize.height = (int) (sourceSize.height / 2);

    // Access the source data bytes
    NSData* sourceData = (NSData*) CGDataProviderCopyData(CGImageGetDataProvider(sourceImage.CGImage));
    unsigned char* sourceBytes = (unsigned char *)[sourceData bytes];

    // Some info we'll need later
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(sourceImage.CGImage);
    int bitsPerComponent = CGImageGetBitsPerComponent(sourceImage.CGImage);
    int bitsPerPixel = CGImageGetBitsPerPixel(sourceImage.CGImage);
    int __attribute__((unused)) bytesPerPixel = bitsPerPixel / 8;
    int sourceBytesPerRow = CGImageGetBytesPerRow(sourceImage.CGImage);
    CGColorSpaceRef colorSpace = CGImageGetColorSpace(sourceImage.CGImage);

    assert(bytesPerPixel == 4);
    assert(bitsPerComponent == 8);

    // Bytes per row is (apparently) rounded to some boundary
    assert(sourceBytesPerRow >= ((int) sourceSize.width) * 4);
    assert([sourceData length] == ((int) sourceSize.height) * sourceBytesPerRow);

    // Allocate target data bytes
    int targetBytesPerRow = ((int) targetSize.width) * 4;
    // Algorigthm happier if bytes/row a multiple of 16
    targetBytesPerRow = (targetBytesPerRow + 15) & 0xFFFFFFF0;
    int targetBytesSize = ((int) targetSize.height) * targetBytesPerRow;
    unsigned char* targetBytes = (unsigned char*) malloc(targetBytesSize);
    UIImage* targetImage = nil;

    // Copy source to target, averaging 4 pixels into 1
    for (int row = 0; row < targetSize.height; row++) {
        unsigned char* sourceRowStart = sourceBytes + (2 * row * sourceBytesPerRow);
        unsigned char* targetRowStart = targetBytes + (row * targetBytesPerRow);
        for (int column = 0; column < targetSize.width; column++) {

            int sourceColumnOffset = 2 * column * 4;
            int targetColumnOffset = column * 4;

            unsigned char* sourcePixel = sourceRowStart + sourceColumnOffset;
            unsigned char* nextRowSourcePixel = sourcePixel + sourceBytesPerRow;
            unsigned char* targetPixel = targetRowStart + targetColumnOffset;

            uint32_t* sourceWord = (uint32_t*) sourcePixel;
            uint32_t* nextRowSourceWord = (uint32_t*) nextRowSourcePixel;
            uint32_t* targetWord = (uint32_t*) targetPixel;

            uint32_t sourceWord0 = sourceWord[0];
            uint32_t sourceWord1 = sourceWord[1];
            uint32_t sourceWord2 = nextRowSourceWord[0];
            uint32_t sourceWord3 = nextRowSourceWord[1];

            // This apparently bizarre sequence scales the data bytes by 4 so that when added together we'll get an average.  We do lose the least significant bits this way, and thus about half a bit of resolution.
            sourceWord0 = (sourceWord0 & 0xFCFCFCFC) >> 2;
            sourceWord1 = (sourceWord1 & 0xFCFCFCFC) >> 2;
            sourceWord2 = (sourceWord2 & 0xFCFCFCFC) >> 2;
            sourceWord3 = (sourceWord3 & 0xFCFCFCFC) >> 2;

            uint32_t resultWord = sourceWord0 + sourceWord1 + sourceWord2 + sourceWord3;
            targetWord[0] = resultWord;
        }
    }

    // Convert the bits to an image.  Supposedly CGCreateImage will dispose of the target bytes buffer.
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, targetBytes, targetBytesSize, NULL);
    CGImageRef targetRef = CGImageCreate(targetSize.width, targetSize.height, bitsPerComponent, bitsPerPixel, targetBytesPerRow, colorSpace, bitmapInfo, provider, NULL, FALSE, kCGRenderingIntentDefault);
    targetImage = [UIImage imageWithCGImage:targetRef];

    // Clean up
    CGColorSpaceRelease(colorSpace);

    // Return result
    return targetImage;
}