以前ブログに書いた 新たに自分専用Web記事保存アプリの開発を始めた、 新たに自分専用Web記事保存アプリその2 iOSアプリですが現在も使っています。
このアプリは、いつか役に立つかもしれないWeb記事をPDFに変換し保存できるアプリです。
保存したWeb記事が実際に役立ったことはは数回しかありませんが、いつか役に立つかもしれないという気持ちを否定せず、ただただ保存できるのが、このアプリの良いところです! バックエンドにはFirebaseを使っていますが今のところ無料で使えています。😁
https://www.flickr.com/photos/seanfx/14337700149より
サムネイル画像がへん
保存した記事の一覧にはWebページの一部をサムネール画像で表示しているのですが、最近なんかへんです。画像がとても小さいです!?
昔キャプチャーしたWebページのサムネイルは下の画像のように、Webページの最初の方がちゃんと234x256dotで表示されています。
調査開始
なぜだろうと、調査を開始しました。サムネイル画像を作るところは以下のようになっています。
簡単に説明すると、
- PDFに変換されたWebページから1ページ目を取り出す
- サムネイル画像の縦横比からサムネール画像に変換するPDFエリアの高さを計算
- 上で計算されたエリアのPDFのみが画像に変換されるように領域を指定
- PDFからサムネイル画像に変換しPNG画像データを取得
func thumbOfPDF(pdfPath: String, thumbSize: CGSize) -> Data {
let pdfPage = PDFDocument(url: URL(fileURLWithPath: pdfPath))!.page(at: 0)! // ①
let rect = pdfPage.bounds(for: .trimBox)
let height = rect.size.width * (thumbSize.height / thumbSize.width) // ②
pdfPage.setBounds(CGRect(x: 0, y: rect.size.height - height,
width: rect.size.width, height: height), for: .trimBox) // ③
return pdfPage.thumbnail(of: thumbSize, for: .trimBox).pngData()! // ④
}
調べてみると、③で設定したエリアが無視されPDF全体からサムネイル画像を作っているようです。
2021年9月23日にリリースされた iOS12.5.5以降から、この現象が起きているようです。iOSのバグまたは仕様変更でしょうか?
対応
iOSのバグであればいつか修正されるかもしれませんが、仕様変更ならずっとこのままです。そこでコードを変更することにしました。😭
- まずサムネイル画像の幅に合わせ、PDF全体のサムネイル画像を作成します
- サムネイル画像の高さに合わせ、サムネイル画像の上の方のみを取り出します(トリミング)
- 上で出来た画像(CGImage)からPNGデータを取得しています
以前のコードに比べると①でやや大きなサムネイル画像を作るので、効率はよくありませんが我慢しましょう。
func thumbOfPDF(pdfPath: String, thumbSize: CGSize) -> Data {
let pdfPage = PDFDocument(url: URL(fileURLWithPath: pdfPath))!.page(at: 0)!
let rect = pdfPage.bounds(for: .mediaBox)
let height = rect.size.height / (rect.size.width / thumbSize.width)
let pdfImage = pdfPage.thumbnail(of: CGSize(width: thumbSize.width, height: height),
for: .mediaBox) // ①
let thumbImage = pdfImage.cgImage!.cropping(to:
CGRect(x: 0.0, y: 0.0, width: thumbSize.width, height: thumbSize.height))! // ②
return UIImage(cgImage: thumbImage).pngData()! // ③
}
既存サムネイルはどうしよう?
さて、これで新規にキャプチャーしたサムネール画像は正しくなりましたが、過去にキャプチャーした91個のサムネール画像はどうしましょうか?
ツールを作ってFirebaseからPDFを取得しサムネール画像を再生成しFirebaseデータを更新するアプリを書きましょうか・・・😭