3

[UIImage initWithData:] を使用して UIImageView の JPEG を生成したい RTSP/UDP 経由の MJPEG ストリームがあります。ほとんどの場合、これで問題なく動作しますが、画像が破損し、次のようなログ メッセージが表示されることがあります。

ImageIO: <ERROR> JPEGCorrupt JPEG data: premature end of data segment

私の質問は次のとおりです。そのようなメッセージが発生したことを(実行時に)どのように確認できますか?残念ながら「initWithData」にはエラー出力がありません。他に方法はありますか?

ありがとうございました。

編集: この場合、initWithData は nil ではなく、有効な UIImage オブジェクトを返します。

4

3 に答える 3

2

スタック オーバーフローに関するこれと同様のスレッドがあります: Catching error: Corrupt JPEG data: premature end of data segment

解決策は、ヘッダー バイトFF D8と終了バイトを確認することFF D9です。したがって、NSData に画像データがある場合は、次のように確認できます。

- (BOOL)isJPEGValid:(NSData *)jpeg {
    if ([jpeg length] < 4) return NO;
    const char * bytes = (const char *)[jpeg bytes];
    if (bytes[0] != 0xFF || bytes[1] != 0xD8) return NO;
    if (bytes[[jpeg length] - 2] != 0xFF || bytes[[jpeg length] - 1] != 0xD9) return NO;
    return YES;
}

次に、JPEG データが無効かどうかを確認するには、次のように記述します。

if (![self isJPEGValid:myData]) {
    NSLog(@"Do something here");
}

お役に立てれば!

于 2011-07-22T13:43:38.777 に答える
1

このような場合、initWithData:メソッドは戻る必要があります。nil

試す :

UIImage *myImage = [[UIImage alloc] initWithData:imgData];
if(!myImage) {
    // problem
}
于 2011-07-22T09:37:14.807 に答える
-1

この正確な状況で同じ問題が発生しました。

デコードのために NSMutableData のインスタンスをグローバル キューに渡していたことが判明しました。NSMutableData のデータのデコード中に、ネットワークから受信した次のフレームによって上書きされました。

データのコピーを渡すことでエラーを修正しました。パフォーマンスを改善するには、バッファー プールを使用する方がよい場合があります。

    NSData *dataCopy = [_receivedData copy];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    ZAssert([self isJPEGValid:dataCopy], @"JPEG data is invalid"); // should never happen
    UIImage *image = [UIImage imageWithData:dataCopy];
    dispatch_async(dispatch_get_main_queue(), ^{
        // show image
    });
});
于 2013-11-23T16:54:21.947 に答える