QLThumbnailGenerator无法生成缩略图。

3

我尝试在iOS和iPadOS的模拟器/设备上使用QLThumbnailGenerator,但它不起作用。我只能获得标准的空缩略图,而不能从我的文档目录中获取丰富的文件图标。

在沙盒中处理文件有一些进展,但没有什么有用的信息。

你能让它工作吗?也许权限有问题...但是哪里出了问题?从我的应用程序中,我可以列出文件并读取(打开)它们。

@IBAction func generateDidSelect(_ sender: Any) {  

    let docDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last  
    print("DOC: \(docDir)")  

    let absPath = URL(fileURLWithPath: docDir ?? "").appendingPathComponent("flowers.png").absoluteString  
    //[[NSBundle mainBundle]URLForResource:@"flowers" withExtension:@"png"];  
    let fileURL = URL(fileURLWithPath: absPath)  
    fileURL.startAccessingSecurityScopedResource()  

    let size = CGSize(width: 200, height: 200)  
    let scale = UIScreen.main.scale  

    let isFile = fileURL.isFile()  
    let exists = FileManager.default.fileExists(atPath: fileURL.path)  
    print("isFILE? \(isFile ? "YES" : "NO") exists? \(exists ? "YES" : "NO") \nFILE: \(fileURL)")  

    let request = QLThumbnailGenerationRequest(fileAtURL: fileURL, size: size, scale: scale, representationTypes: QLThumbnailGenerationRequestRepresentationTypeAll)  
    //request.iconMode = YES;  

    QLThumbnailGenerator.shared().generateRepresentations(for: request, updateHandler: { thumbnail, type, error i  

        DispatchQueue.main.async(execute: {  

            print(String(format: "*** TYPE: %ld ****", Int(type)))  
            let uiimage = thumbnail?.uiImage  
            let cgImage = thumbnail?.cgImage  

            if let uiimage = uiimage {  
                print("uiimage: \(uiimage)")  
            }  
            if let cgImage = cgImage {  
                print("cgImage: \(cgImage)")  
           }  

            if uiimage != nil {  
                self.thumbnailImageView.image = uiimage  
            }  

            if error != nil {  
                if let error = error {  
                    print("ERROR: \(error)")  
                }  
                //self.thumbnailImageView.image = [UIImage imageWithContentsOfFile:fileURL.path]; // test read, works  
            }  
        })  
    })  

}  

然后我尝试将一张图片放入bundle文件夹中。

使用以下代码获取文件的URL:

Bundle.main.url(forResource: "flowers", withExtension: "png")  

神奇的是它能够正常工作!但是使用fileURLWithPath方法时则不行。

然而,当我尝试访问通过iTunes上传到应用程序文档目录中的相同文件时,出现了读取错误。

2019-10-01 12:41:27.167091+0200 test_thumb_obj[618:57118] DOC: /var/mobile/Containers/Data/Application/BE4A5950-5D24-4620-A1FE-B837222E8B64/Documents  
2019-10-01 12:41:27.196739+0200 test_thumb_obj[618:57118] isFILE? YES exists? YES   
FILE: file:///var/mobile/Containers/Data/Application/BE4A5950-5D24-4620-A1FE-B837222E8B64/Documents/flowers.png  
2019-10-01 12:41:27.233546+0200 test_thumb_obj[618:57118] *** TYPE: 0 ****  
2019-10-01 12:41:27.233788+0200 test_thumb_obj[618:57118] uiimage:   
2019-10-01 12:41:27.233858+0200 test_thumb_obj[618:57118] cgImage:  (DP)  
  < (kCGColorSpaceDeviceRGB)>  
  width = 493, height = 640, bpc = 8, bpp = 32, row bytes = 1984   
  kCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Little  | kCGImagePixelFormatPacked   
  is mask? No, has masking color? No, has soft mask? No, has matte? No, should interpolate? Yes  
2019-10-01 12:41:27.234761+0200 test_thumb_obj[618:57118] *** TYPE: 1 ****  
2019-10-01 12:41:27.234836+0200 test_thumb_obj[618:57118] uiimage: (null)  
2019-10-01 12:41:27.234865+0200 test_thumb_obj[618:57118] cgImage: (null)  
2019-10-01 12:41:27.234943+0200 test_thumb_obj[618:57118] ERROR: Error Domain=QLThumbnailErrorDomain Code=2 "No cached thumbnail"  
2019-10-01 12:41:27.262228+0200 test_thumb_obj[618:57118] *** TYPE: 2 ****  
2019-10-01 12:41:27.262317+0200 test_thumb_obj[618:57118] uiimage: (null)  
2019-10-01 12:41:27.262349+0200 test_thumb_obj[618:57118] cgImage: (null)  
2019-10-01 12:41:27.262452+0200 test_thumb_obj[618:57118] ERROR: Error Domain=QLThumbnailErrorDomain Code=0 "Could not generate a thum  
bnail" UserInfo={NSUnderlyingError=0x281676940 {Error Domain=NSCocoaErrorDomain Code=256 "The file couldn’t be opened."}}  

我只获得了一个 i TYPE = 0 的图像,是一个白色的空图像。

而且,与之前一样,在模拟器上也没有什么好的结果......

Error Domain=NSPOSIXErrorDomain Code=22 "couldn't issue sandbox extension com.apple.app-sandbox.read for...  

有些测试我错过了,导致它无法正常工作?

3个回答

2

我也遇到了同样的问题。我通过将 representationTypes 从 .all 更改为 .thumbnail 来解决它。

let request = QLThumbnailGenerator
            .Request(fileAt: fileURL, size: size, scale: scale,
                     representationTypes: .thumbnail)

或者,如果您愿意,可以尝试创建递归。在调用generateRepresentations 20-30 次后,错误“未缓存的缩略图”停止出现,图片将变得可用。

func thumbnail(for fileURL: URL, size: CGSize, scale: CGFloat) {
    QLThumbnailGenerator.shared.generateRepresentations(for: request) { (thumbnail, type, error) in

        let uiimage = thumbnail?.uiImage
        if uiimage == nil {
             thumbnail(fileURL, size, scale)
        }
        else {
             //image is available
        }
    }
}

我不认为递归是合适的,但现在我对模拟器上的虚拟缩略图和设备真实图标感到满意。 - Fabiosoft

0
在iOS13.2 beta上解决了。 设备上没问题,但模拟器上仍然存在阅读问题。

0

这对我有用,我创建了这个方法:

import QuickLook

...

func generateThumbnailFromQuickLook(url: URL,
                                    type: QLThumbnailGenerator.Request.RepresentationTypes,
                                    completionHandler: @escaping (Bool, UIImage?) -> Void) {
    let size = CGSize(width: 300, height: 250)
    let scale = UIScreen.main.scale
    
    let request = QLThumbnailGenerator.Request(fileAt: url,
                                               size: size,
                                               scale: scale,
                                               representationTypes: type)
    
    let generator = QLThumbnailGenerator.shared
    
    generator.generateBestRepresentation(for: request) { thumbnail, error in
        if let error = error {
            print(error)
        }
        
        completionHandler(thumbnail != nil, thumbnail?.uiImage)
    }
}

然后,我检查表示类型缩略图是否失败。 如果失败了,我尝试获取表示类型全部

let url: URL = <url file>

generateThumbnailFromQuickLook(url: url, type: .thumbnail) { success, image in
    if success == false {
        generateThumbnailFromQuickLook(url: url, type: .all) { success, image in
            // use the thumbnail here
        }
    } else if let image = image {
        // use the thumbnail here
    }
}


我做了同样的事情,只是在模拟器上退而求其次,但在设备上运行良好。 - Fabiosoft

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接