1
CGImageRef        thumbnailImage = NULL;
CGImageSourceRef  imageSource = NULL;
CFDictionaryRef   createOptions = NULL;
CFStringRef       createKeys[3];
CFTypeRef         createValues[3];
CFNumberRef       thumbnailSize = 0;
UIImage * thumbnail;
NSData * squareData = UIImagePNGRepresentation(sourceImage);
NSData * thumbnailData = nil;

imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)squareData,NULL);
if (imageSource)
{
    thumbnailSize = CFNumberCreate(NULL, kCFNumberIntType, &imageSize);
    if (thumbnailSize)
    {
        createKeys[0] = kCGImageSourceCreateThumbnailWithTransform;
        createValues[0] = (CFTypeRef)kCFBooleanTrue;
        createKeys[1] = kCGImageSourceCreateThumbnailFromImageIfAbsent;
        createValues[1] = (CFTypeRef)kCFBooleanTrue;
        createKeys[2] = kCGImageSourceThumbnailMaxPixelSize;
        createValues[2] = (CFTypeRef)thumbnailSize;

        createOptions = CFDictionaryCreate(NULL, (const void **) createKeys,
                createValues, sizeof(createValues)/ sizeof(createValues[0]),
                &kCFTypeDictionaryKeyCallBacks,
                & kCFTypeDictionaryValueCallBacks);
        if (createOptions)
        {
            thumbnailImage = CGImageSourceCreateThumbnailAtIndex(imageSource,0,createOptions);
            if(thumbnailImage)
            {
                thumbnail = [UIImage imageWithCGImage:thumbnailImage];
                if (thumbnail)
                {
                    thumbnailData = UIImagePNGRepresentation(thumbnail);
                }
            }
        }
    }
}

thumbnailData.lengthiOS12で同じ画像でも違う値を取得。CGImageSourceCreateThumbnailAtIndex()パラメータとして使用して渡すサムネイル画像を作成しようとしてsourceImageいます。iOS12のバグですか?回避策はありますか?iOS12ベータ4を使用しています。

4

1 に答える 1

2

データサイズ異なりますが、結果の画像は問題ありません。彼らは明らかにアルゴリズムにいくつかの非常に控えめな変更を加えました. しかし、ここにはバグはありません。

個人的には、次の 2 つの変更点に気付きました。

  • 正方形でない画像では、サムネイルのサイズを決定するアルゴリズムが明らかに変更されています。たとえば、サンプルの 3500×2335 ピクセルの画像で 100 ピクセルのサムネイルを作成すると、iOS 12.2 では 100×67 ピクセルの画像になりましたが、iOS 11.0.1 では 100×66 ピクセルになりました。

  • 正方形の画像では、iOS の 2 つのバージョンは両方とも適切な正方形のサムネイルを生成しました。画像自体に関しては、肉眼で観察できる違いはあまり見られませんでした。実際、私はこれを Photoshop にドロップして違いを分析しました (ここで、黒 == 違いはありません)。最初はまったく変化がないように見えました。

    ここに画像の説明を入力

    本当にピクセルのぞき見を始めて初めて、非常に控えめな変化を検出できました。UInt8個々のチャネルが (これらの値で) 1 または 2 以上異なることはめったにありません。これは同じ差分画像です。今回はレベルが吹き飛ばされているため、違いがわかります。

    ここに画像の説明を入力

要するに、明らかにアルゴリズムにいくつかの変更がありますが、それをバグとは見なしません。ただ違うだけですが、うまくいきます。


無関係な観察では、コードにいくつかのリークがあります。Core Foundation メソッドの名前にCreateorCopyが含まれている場合は、それを解放する責任があります (または、ブリッジされた型では、所有権を ARC に譲渡しますが、これはここではオプションではありません)。静的アナライザーshift+ command+Bは、これらの問題の特定に優れています。

FWIW、これが私の表現です:

- (UIImage * _Nullable)resizedImage:(UIImage *)sourceImage to:(NSInteger)imageSize {
    NSData *squareData = UIImagePNGRepresentation(sourceImage);
    UIImage *thumbnail = nil;

    CGImageSourceRef imageSource = CGImageSourceCreateWithData((CFDataRef)squareData, NULL);
    if (imageSource) {
        NSDictionary *createOptions = @{
            (id)kCGImageSourceCreateThumbnailWithTransform: @true,
            (id)kCGImageSourceCreateThumbnailFromImageIfAbsent: @true,
            (id)kCGImageSourceThumbnailMaxPixelSize: @(imageSize)
        };
        CGImageRef thumbnailImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, (CFDictionaryRef)createOptions);
        if (thumbnailImage) {
            thumbnail = [UIImage imageWithCGImage:thumbnailImage];
            if (thumbnail) {
                NSData *data = UIImagePNGRepresentation(thumbnail);
                // do something with `data` if you want
            }
            CFRelease(thumbnailImage);
        }
        CFRelease(imageSource);
    }

    return thumbnail;
}
于 2019-03-22T17:48:54.740 に答える