みんな:
私はこれに何日も取り組んできました。ここで少し背景を説明します。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 に変換します。
- UIImageを取る
- そこから NSData を取得します
- データを unsigned char * に変換します
- unsigned char * を std::string に詰め込みます
文字列は、protobuf 呼び出しから受け取るものです。パート 2 では、文字列からデータを取得し、それを NSData 形式に変換して UIImage に入力します。そのための手順は次のとおりです。
- std::string を char 配列に変換します
- char 配列を const char に変換します *
- char * を NSData に入れる
- 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 one、this one、this oneなど、SOに関する他の質問をいくつか試しましたが、解決に必要な情報が見つかりません。私の問題の一部は、画像(RGBA値やその他のものなど)についてあまり理解していないことです。