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 は常に nil でした。 This tells me that my NSData is not in the correct format.

以前の質問here で示されているように、最初は、私の問題は 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];

以下は、私が最終的に行う必要があることの説明です。2 つの部分があります。パート 1 では、UIImage を受け取り、それを std::string に変換します。

  1. UIImageを取る
  2. そこから NSData を取得します
  3. データを unsigned char * に変換します
  4. unsigned char * を std::string に詰め込みます

文字列は、protobuf 呼び出しから受け取るものです。パート 2 では、文字列からデータを取得し、それを NSData 形式に変換して UIImage に入力します。そのための手順は次のとおりです。

  1. std::string を char 配列に変換します
  2. char 配列を const char に変換します *
  3. char * を NSData に入れる
  4. NSData を返す

さて、その背景情報と、UIImage に CGImageRef を入力することが機能するという事実、つまり、その形式のデータが 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;
}

何気ない観察者ならわかると思いますが、私には助けが必要です。ヘルプ!!!this onethis onethis oneなど、SOに関する他の質問をいくつか試しましたが、解決に必要な情報が見つかりません。私の問題の一部は、画像(RGBA値やその他のものなど)についてあまり理解していないことです。

4

0 に答える 0