1

webpアニメーション画像を表示するのに2日間苦労しましたがUIImageView、まったく成功しませんでした。

主に問題は、このエラーを発生させるファイルのデコード手順にあります: VP8_STATUS_UNSUPPORTED_FEATURE.

私は試した

https://github.com/seanooi/iOS-WebP

https://github.com/mattt/WebPImageSerialization

これらのプロジェクトは、ファイルを作成するためのコードを提供UIImagewebp、アニメーションのない画像では問題なく動作しますが、アニメーションを含む画像をデコードしようとすると、どちらも上記と同じエラーで失敗します。

私はジェイルブレイクしていて、ファイルシステムを確認したところ、Facebookのメッセンジャーアプリにはステッカーの.webpフォーマットがいくつかあり、ライセンスにもGoogleの「webp」ライブラリが記載されているので、何とかそれが可能であると確信しています.

4

1 に答える 1

3

このヘッダーの上部にあるコード スニペットを使用して、アニメーション化された .webp をデコードできました。これには、使用されているデータ構造の説明も含まれています。

static NSDictionary* DecodeWebPURL(NSURL *url) {

            NSMutableDictionary *info = [NSMutableDictionary dictionary];
            NSMutableArray *images = [NSMutableArray array];
            NSData *imgData = [NSData dataWithContentsOfURL:url];

            WebPData data;
            WebPDataInit(&data);

            data.bytes = (const uint8_t *)[imgData bytes];
            data.size = [imgData length];

            WebPDemuxer* demux = WebPDemux(&data);

            int width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
            int height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
            uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);

            if (flags & ANIMATION_FLAG) {
                WebPIterator iter;
                if (WebPDemuxGetFrame(demux, 1, &iter)) {

                    WebPDecoderConfig config;
                    WebPInitDecoderConfig(&config);

                    config.input.height = height;
                    config.input.width = width;
                    config.input.has_alpha = iter.has_alpha;
                    config.input.has_animation = 1;
                    config.options.no_fancy_upsampling = 1;
                    config.options.bypass_filtering = 1;
                    config.options.use_threads = 1;
                    config.output.colorspace = MODE_RGBA;

                    [info setObject:[NSNumber numberWithInt:iter.duration] forKey:@"duration"];

                    do {
                        WebPData frame = iter.fragment;

                        VP8StatusCode status = WebPDecode(frame.bytes, frame.size, &config);
                        if (status != VP8_STATUS_OK) {
                            NSLog(@"Error decoding frame");
                        }

                        uint8_t *data = WebPDecodeRGBA(frame.bytes, frame.size, &width, &height);
                        CGDataProviderRef provider = CGDataProviderCreateWithData(&config, data, config.options.scaled_width  * config.options.scaled_height * 4, NULL);

                        CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
                        CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaLast;
                        CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

                        CGImageRef imageRef = CGImageCreate(width, height, 8, 32, 4 * width, colorSpaceRef, bitmapInfo, provider, NULL, YES, renderingIntent);
                        [images addObject:[UIImage imageWithCGImage:imageRef]];
                        CGImageRelease(imageRef);
                        CGColorSpaceRelease(colorSpaceRef);
                        CGDataProviderRelease(provider);

                    } while (WebPDemuxNextFrame(&iter));

                    WebPDemuxReleaseIterator(&iter);
                }
            }
            WebPDemuxDelete(demux);
            [info setObject:images forKey:@"frames"];

            return info;
        }
于 2015-02-12T08:35:08.777 に答える