Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 带有NSData initWithData的UIImage返回nil_C++_Objective C_String_Uiimage_Nsdata - Fatal编程技术网

C++ 带有NSData initWithData的UIImage返回nil

C++ 带有NSData initWithData的UIImage返回nil,c++,objective-c,string,uiimage,nsdata,C++,Objective C,String,Uiimage,Nsdata,我有一个新问题!因为真正的问题不在C++转换中,而是需要将返回的字符串数据字节转换成CGIMAVEREF。任何人都知道如何做到这一点,请转到该链接来回答这个问题的后续部分 多谢各位 嗯。我没有用protobuf的东西把问题弄得一团糟,而是简化了我的测试方法来模拟对protobuf的调用 本试验方法包括以下两部分。第1部分获取UIImage并将其转换为std::字符串 拍照 从中获取数据 将数据转换为无符号字符* 将无符号字符*填充到std::字符串中 字符串是我们将从protobuf调用中接收的

我有一个新问题!因为真正的问题不在C++转换中,而是需要将返回的字符串数据字节转换成CGIMAVEREF。任何人都知道如何做到这一点,请转到该链接来回答这个问题的后续部分

多谢各位

嗯。我没有用protobuf的东西把问题弄得一团糟,而是简化了我的测试方法来模拟对protobuf的调用

本试验方法包括以下两部分。第1部分获取UIImage并将其转换为std::字符串

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

将std::string转换为char数组 将字符数组转换为常量字符* 将字符*放入NSData 返回NSData 返回数据时的代码:

    NSData *data = [self.messageCommand testProcessedImage:processedImage];

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

在我尝试用数据创建UIImage之前,一切似乎都按计划进行。Alloc使用该数据初始化UIImage时返回nil。必须有某种类型的转换来实现这项工作。

OK,所以问题很可能是Objto-C、C和C++数据结构之间的重复转换。总的来说,您需要确保将字符串初始化为字节数组而不是文本C字符串,并且希望在不使用空终止符的情况下返回原始字节。我认为这将正确保存数据:

- (void)onDataReceived:(NSNotification *)note {
    if ([note.name isEqualToString:@"DataReceived"]) {
        NSDictionary *userData = note.userInfo;
        NSData *imageData = [userData objectForKey:@"ImageData"];
 // Note the two-argument string constructor -- this is necessary for non-textual data!
        std::string byteString = std::string(static_cast<const char*>([imageData bytes]), imageData.length);


 // We get the image back as a std::string
        std::string imageStr = [self.message parseMessage:byteString ofSize:byteString.size()];
        NSLog(@"examine imageStr");

 // We get the data from the std::string
        char *imageCStr = new char[imageStr.size()];
        imageStr.copy(imageCStr, imageStr.size());
        NSData *data = [NSData dataWithBytes:imageCStr length:imageStr.size()];
        delete[] imageCStr;

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

我试着回答。我需要做一些小改动来消除错误。此外,我还更改了一些变量名,以尽量减少混淆。对于UIImage,这仍然返回nil

- (void)onObjectReceived:(NSNotification *)note {
    if ([note.name isEqualToString:@"ObjectReceived"]) {
        NSDictionary *userData = note.userInfo;
        NSData *objectData = [userData objectForKey:@"ObjectData"];

        // Added this because bytes is used below.  Or did you mean something else?
        const char *bytes = (const char *)[objectData bytes];

        // Note the two-argument string constructor -- this is necessary for non-textual data!
        std::string byteString = std::string(static_cast<const char*>(bytes), objectData.length);

        // This is an out parameter in the parseMessage method.
        long unsigned int *msgSize = (long unsigned *)malloc(sizeof(long unsigned int));

        // We get the image back as a std::string
        std::string imageStr = [self.message parseMessage:byteString outMsgSize:msgSize];
        NSLog(@"examine imageStr");

        // We get the data from the std::string
        char *imageCStr = new char[imageStr.size()];
        imageStr.copy(imageCStr, imageStr.size());
        NSData *data = [NSData dataWithBytes:imageCStr length:imageStr.size()];
        delete[] imageCStr;

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

我试着移除中间的所有东西,结果成功了。代码如下:

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

    UIImage *image = [UIImage imageWithCGImage:imageRef];
这告诉我NSData DATAWITH字节不起作用,因为我使用的是CGImageRef。我的图像是来自相机的原始数据,不是PNG或JPEG

我发现这很有帮助。提问者甚至发布了这条评论,将数据包装在CFData对象中,然后使用CGDataProviderCreateWithCFData看起来非常简单

我发现这也很有帮助。它显示了如何使用字符串创建CFDataRef

有很多有用的信息,但仍然没有找到我需要的。我要问另一个问题,当我得到答案时,再回到这里


谢谢。

有人怀疑您的NSData对象无效。这是一种复杂的代码,不知道IDMessageWrapper是什么。为什么要接收NSData,将其转换为std:string,然后返回NSData??这几乎肯定会损坏数据。第一个NSData是使用protobuf返回的对象。第二个NSData是以字节为单位的实际图像。@AaronGolden:Great point。std::string的构造也容易受此影响,因为它使用const char*构造函数而不是const char*,size\t one。除了使用Base64之外,没有其他方法可以将NSData转换为c_str并返回,而不会损坏数据。我试过你的代码。它运行得很好,但我的图像仍然是零。请参阅我的答案以获取代码。我不得不改变一些事情。你能看一下我的更改是否与你试图提供的不一致吗?谢谢你。@Lucy:你肯定明白我说的了。如果我不熟悉您在这里使用的协议缓冲库,那么我真的无法判断imageStr的创建是否有问题,但这是我唯一能想到的。我在这里为整体数据->cstring->string和string->cstring->data流做了一个小测试程序,并用一些示例数据运行它,它似乎很好地保留了数据。我简化了代码和我的原始问题,删除了所有与将图像转换为std::string并返回到NSData以创建新数据无关的内容UIImage。但新的UIImage仍然为零。你能看一下吗?非常感谢。
- (NSData *)testProcessedImage:(UIImage *)processedImage
{
    // UIImage to unsigned char *
    CGImageRef imageRef = processedImage.CGImage;
    NSData *data1 = (NSData *) CFBridgingRelease(CGDataProviderCopyData(CGImageGetDataProvider(imageRef)));

    UIImage *image = [UIImage imageWithCGImage:imageRef];