Closed9

【Swift】Image&PDF 0->1

yoshitakayoshitaka

Images and PDF

Create and manage images, including those that use bitmap and PDF formats.
Framework
ビットマップおよびPDF形式を使用する画像を含む画像を作成および管理します。
フレームワーク

yoshitakayoshitaka

Image Creation

func UIGraphicsBeginImageContext(CGSize)

ビットマップベースのグラフィックスコンテキストを作成し、それを現在のコンテキストにします。
Creates a bitmap-based graphics context and makes it the current context.
現在のグラフィックスコンテキストはデフォルトでnilです。 そのdrawRect:メソッドを呼び出す前に、ビューオブジェクトは有効なコンテキストをスタックにプッシュし、それを最新のものにします。 ただし、UIViewオブジェクトを使用して描画を行っていない場合は、UIGraphicsPushContext(_ :)関数を使用して、有効なコンテキストを手動でスタックにプッシュする必要があります。

この関数は、アプリのどのスレッドからでも呼び出すことができます。

func UIGraphicsGetImageFromCurrentImageContext() -> UIImage?

現在のビットマップベースのグラフィックスコンテキストのコンテンツから画像を返します。
Returns an image from the contents of the current bitmap-based graphics context.

この関数は、ビットマップベースのグラフィックスコンテキストが現在のグラフィックスコンテキストである場合にのみ呼び出す必要があります。 現在のコンテキストがnilであるか、UIGraphicsBeginImageContext(_ :)の呼び出しによって作成されていない場合、この関数はnilを返します。

この関数は、アプリのどのスレッドからでも呼び出すことができます。

func UIGraphicsEndImageContext()

現在のビットマップベースのグラフィックスコンテキストをスタックの最上位から削除します。
Removes the current bitmap-based graphics context from the top of the stack.

func jpegData(compressionQuality: CGFloat) -> Data?

指定された画像を含むデータオブジェクトをJPEG形式で返します。
Returns a data object that contains the specified image in JPEG format.

func pngData() -> Data?

指定された画像を含むデータオブジェクトをPNG形式で返します。
Returns a data object that contains the specified image in PNG format.

yoshitakayoshitaka

https://faboplatform.github.io/SwiftDocs/1.uikit/060_uiimage/

extension UIImage {

    /*
     画像をResizeするクラスメソッド.
     */
    class func ResizeÜIImage(image : UIImage,width : CGFloat, height : CGFloat)-> UIImage!{

        // 指定された画像の大きさのコンテキストを用意.
        UIGraphicsBeginImageContext(CGSize(width: width, height: height))

        // コンテキストに画像を描画する.
        image.draw(in: CGRect(x: 0, y: 0, width: width, height: height))

        // コンテキストからUIImageを作る.
        let newImage = UIGraphicsGetImageFromCurrentImageContext()

        // コンテキストを閉じる.
        UIGraphicsEndImageContext()

        return newImage
    }

    /*
     画像を合成するクラスメソッド.
     */
    class func ComposeUIImage(UIImageArray : [UIImage], width: CGFloat, height : CGFloat)->UIImage!{

        // 指定された画像の大きさのコンテキストを用意.
        UIGraphicsBeginImageContext(CGSize(width: width, height: height))

        // UIImageのある分回す.
        for image : UIImage in UIImageArray {

            // コンテキストに画像を描画する.
            image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
        }

        // コンテキストからUIImageを作る.
        let newImage = UIGraphicsGetImageFromCurrentImageContext()

        // コンテキストを閉じる.
        UIGraphicsEndImageContext()

        return newImage
    }
}

class ViewController: UIViewController {

    override func viewDidLoad() {

        // 1つ目のUIImageを作る.
        var myImage1 = UIImage(named: "sample1")!

        // リサイズする.
        myImage1 = UIImage.ResizeÜIImage(image: myImage1,width: self.view.frame.maxX, height: self.view.frame.maxY)

        // 2つ目のUIImageを作る.
        var myImage2 = UIImage(named: "sample2")!

        // リサイズする.
        myImage2 = UIImage.ResizeÜIImage(image: myImage2,width: self.view.frame.midX, height: self.view.frame.midY)

        // 画像を合成する.
        let ComposedImage = UIImage.ComposeUIImage(UIImageArray: [myImage1, myImage2], width: self.view.frame.maxX, height: self.view.frame.maxY)

        // UIImageViewに合成されたUIImageを指定する.
        let myImageView = UIImageView(image: ComposedImage)

        self.view.addSubview(myImageView)
    }
}
yoshitakayoshitaka

つまり画像に画像を入れ込む実装においては

UIGraphicsBeginImageContext(CGSize(width: width, height: height)) こいつの縦横の長さが入れ込む箱の大きさ

image.draw(in: CGRect(x: 0, y: 0, width: width, height: height)) こいつの縦横の長さが入れ込む画像自体の大きさ

ってことか

yoshitakayoshitaka

(320.0, 518.0) お絵描きビューのサイズ
Optional((534.0, 934.0)) コート画像サイズ
(320.0, 518.0) コート画像ビューのサイズ
Optional((534.0, 934.0)) コート画像に入れ込んだimageのサイズ(リサイズされても値は変わらない?)

(0.0, 0.0, 320.0, 518.0) 親ビューframe (ストーリーボードサイズ 間違ってSE1にしてた)
(0.0, 0.0, 320.0, 518.0) 親ビューbounds
(0.0, 0.0, 0.0, 0.0) メインビュー
(0.0, 0.0, 0.0, 0.0) お絵描きビュー

(0.0, 0.0, 320.0, 518.0) 親ビューframe
(0.0, 0.0, 320.0, 518.0) 親ビューbounds
(0.0, 0.0, 320.0, 518.0) メインビュー
(0.0, 0.0, 320.0, 518.0) お絵描きビュー

(0.0, 0.0, 375.0, 553.0) 親ビューframe (ここで実サイズに変わった?)
(0.0, 64.0, 375.0, 553.0) 親ビューbounds (Yが変わったから無視した方が良さそう)
(0.0, 0.0, 320.0, 518.0) メインビュー
(0.0, 0.0, 320.0, 518.0) お絵描きビュー

(0.0, 0.0, 375.0, 553.0) 親ビューframe
(0.0, 64.0, 375.0, 553.0) 親ビューbounds
(0.0, 0.0, 375.0, 553.0) メインビュー
(0.0, 0.0, 375.0, 553.0) お絵描きビュー

ここで色々調べたが、分からず。結局このあたりを読みライブラリーを使うことに

https://qiita.com/KikurageChan/items/145dd30dfa57c84ebae4
https://qiita.com/marty-suzuki/items/a28269ee39b6e0ec0830
https://tech.librastudio.co.jp/entry/index.php/2018/04/08/post-1855/
https://github.com/daihase/Sketch

yoshitakayoshitaka

quality .high .default
Optional((534.0, 934.0)) lessonImage?.size
(375.0, 617.0) sketchView.frame.size
(0.0, 64.0, 375.0, 553.0) sketchView.frame
Optional((375.0, 617.0)) print(savingImage?.size)

Optional((750.0, 1234.0)) lessonImage?.size
(375.0, 617.0) sketchView.frame.size
(0.0, 64.0, 375.0, 553.0) sketchView.frame
Optional((375.0, 617.0)) print(savingImage?.size)

Optional((750.0, 1234.0)) lessonImage?.size
(375.0, 617.0) sketchView.frame.size

.medium
Optional((534.0, 934.0))
(375.0, 617.0)
(0.0, 64.0, 375.0, 553.0)
Optional((375.0, 617.0))
Optional((750.0, 1234.0))
(375.0, 617.0)
(0.0, 64.0, 375.0, 553.0)
Optional((375.0, 617.0))
Optional((750.0, 1234.0))
(375.0, 617.0)

結局ナブバーの悪さだった

ナブバーはレイアウトサブビュー後にできるので、タイミング重要

override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        sketchView.loadImage(image: lessonImage!, drawMode: .scale)
        UIGraphicsBeginImageContextWithOptions(sketchView.frame.size, false, 0.0)
        UIGraphicsGetCurrentContext()!.interpolationQuality = .high
    }

これで解決

と思ったらまだダメで、

ViewWillLayoutSubviewsはボタン押してモーダル表示されるたびに呼ばれるので
こっちにしたらうまくいった。

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        sketchView.loadImage(image: lessonImage!, drawMode: .scale)
        UIGraphicsBeginImageContextWithOptions(sketchView.frame.size, false, 0.0)
        UIGraphicsGetCurrentContext()!.interpolationQuality = .high
    }

これ重要だった

このスクラップは2021/09/07にクローズされました