1

每个人:

我已经为此工作了好几天。这里有一点背景。我正在使用 protobuf 将图像发送到服务器。图像直接来自相机,因此它不是 jpeg 也不是 png。我找到了使用 CGImage 从 UIImage 获取数据的代码来创建 CGImageRef。请参阅以下代码:

- (UIImage *)testProcessedImage:(UIImage *)processedImage
{
    CGImageRef imageRef = processedImage.CGImage;
    NSData *data1 = (NSData *) CFBridgingRelease(CGDataProviderCopyData(CGImageGetDataProvider(imageRef)));

Google protobuf 使用 C++ 代码向服务器发送和接收字节。当我尝试将数据字节取回 NSData 并使用该数据分配初始化 UIImage 时,UIImage 始终为零。 This tells me that my NSData is not in the correct format.

起初,我认为我的问题与 C++ 转换有关,如我之前的问题所示。但是在经历了很多挫折之后,我把中间的所有东西都剪掉了,然后用 CGImageRef 创建了一个 UIImage 并且它起作用了。请参阅以下代码:

- (UIImage *)testProcessedImage:(UIImage *)processedImage
{
    CGImageRef imageRef = processedImage.CGImage;
    NSData *data1 = (NSData *) CFBridgingRelease(CGDataProviderCopyData(CGImageGetDataProvider(imageRef)));

    // Added this line and cut out everything in the middle
    UIImage *image = [UIImage imageWithCGImage:imageRef];

以下是我最终需要做的事情的描述。有两个部分。第 1 部分采用 UIImage 并将其转换为 std::string。

  1. 取一个 UIImage
  2. 从中获取 NSData
  3. 将数据转换为无符号字符 *
  4. 将 unsigned char * 填充到 std::string

该字符串是我们将从 protobuf 调用中收到的内容。第 2 部分从字符串中获取数据并将其转换回 NSData 格式以填充 UIImage。以下是执行此操作的步骤:

  1. 将 std::string 转换为 char 数组
  2. 将 char 数组转换为 const char *
  3. 将 char * 放入 NSData
  4. 返回 NSData

现在,有了这些背景信息并掌握了使用 CGImageRef 填充 UIImage 有效的事实,这意味着该格式的数据是填充 UIImage 的正确格式,我正在寻求帮助以了解如何获取 base64。 data() 到 CFDataRef 或 CGImageRef 中。下面是我的测试方法:

- (UIImage *)testProcessedImage:(UIImage *)processedImage
{
    CGImageRef imageRef = processedImage.CGImage;
    NSData *data1 = (NSData *) CFBridgingRelease(CGDataProviderCopyData(CGImageGetDataProvider(imageRef)));

    unsigned char *pixels = (unsigned char *)[data1 bytes];
    unsigned long size = [data1 length];

    // ***************************************************************************
    // This is where we would call transmit and receive the bytes in a std::string
    //
    // The following line simulates that:
    //
    const std::string byteString(pixels, pixels + size);
    //
    // ***************************************************************************

    // converting to base64        
    std::string encoded = base64_encode(reinterpret_cast<const unsigned char*>(byteString.c_str()), byteString.length());

    // retrieving base64        
    std::string decoded = base64_decode(encoded);

    // put byte array back into NSData format
    NSUInteger usize = decoded.length();
    const char *bytes = decoded.data();
    NSData *data2 = [NSData dataWithBytes:(const void *)bytes length:sizeof(unsigned char)*usize];
    NSLog(@"examine data");

    // But when I try to alloc init a UIImage with the data, the image is nil
    UIImage *image2 = [[UIImage alloc] initWithData:data2];
    NSLog(@"examine image2");


    // *********** Below is my convoluted approach at CFDataRef and CGImageRef **************** 

    CFDataRef dataRef = CFDataCreate( NULL, (const UInt8*) decoded.data(), decoded.length() );
    NSData *myData = (__bridge NSData *)dataRef;
    //CGDataProviderRef ref = CGDataProviderCreateWithCFData(dataRef);
    id sublayer = (id)[UIImage imageWithCGImage:imageRef].CGImage;
    UIImage *image3 = [UIImage imageWithCGImage:(__bridge CGImageRef)(sublayer)];

    return image3;
}

正如任何不经意的观察者所见,我需要帮助。帮助!!!我已经尝试过关于 SO 的其他一些问题,例如这个这个这个,但找不到解决方案所需的信息。我承认我的部分问题是我不太了解图像(如 RGBA 值和其他东西)。

4

0 回答 0