Как получить ошибки / предупреждения в [UIImage initWithData:] - PullRequest
3 голосов
/ 22 июля 2011

У меня есть поток MJPEG через RTSP / UDP, из которого я хочу сгенерировать JPEG для UIImageView с [UIImage initWithData:]. В большинстве случаев это работает хорошо, но иногда я получаю испорченные изображения и сообщения в журнале, например:

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

Мой вопрос: как я могу увидеть (во время выполнения), что такое сообщение появляется? К сожалению, initWithData не выдает ошибку, есть ли другой способ?

Спасибо.

Редактировать: в этом случае initWithData возвращает действительный объект UIImage, а не nil!

Ответы [ 3 ]

2 голосов
/ 22 июля 2011

Существует поток, аналогичный этому при переполнении стека: Ошибка перехвата: поврежденные данные JPEG: преждевременный конец сегмента данных .

Существует решение для проверки байтов заголовка 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");
}

Hopeэто помогает!

2 голосов
/ 22 июля 2011

Метод initWithData: должен возвращать nil в таких случаях.

Попробуйте:

UIImage *myImage = [[UIImage alloc] initWithData:imgData];
if(!myImage) {
    // problem
}
0 голосов
/ 23 ноября 2013

Я столкнулся с той же проблемой в этой конкретной ситуации.

Оказалось, что я передаю экземпляр 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
    });
});
...