🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

603閲覧

Swiftにて、読み込んだUIImageのリサイズ、配列操作が上手く動作しない

hkbto

総合スコア14

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/09/11 12:30

前提・実現したいこと

読み込んだ画像をスライダーの数値によってリサイズ、配列操作をした後に表示したい

発生している問題・エラーメッセージ

画像が崩れる

該当のソースコード

Swift

1 { 2 r2 = Slider!.value 3 Katati = UIImage(named: "image.png") 4 let imageResize:UIImage = resize(image: Katati, width: Double(r2*2)) 5 6 var katati_pixels = getByteArrayFromImage(imageRef: imageResize.cgImage!) 7 8 //////////// 9 配列操作 10 //////////// 11 12 let result_pix = RBGImage(data: katati_pixels, width: r2*2, height:r2*2) 13 Button.setImage(UIImage(cgImage: result_pix!), for: UIControl.State.normal) 14 } 15 16 17 func getByteArrayFromImage(imageRef: CGImage) -> [UInt8] { 18 19 let data = imageRef.dataProvider!.data 20 let length = CFDataGetLength(data) 21 var rawData = [UInt8](repeating: 0, count: length) 22 CFDataGetBytes(data, CFRange(location: 0, length: length), &rawData) 23 return rawData 24 25 } 26 func RBGImage(data: [UInt8], width: Int, height: Int) -> CGImage? { 27 28 let bitsPerComponent = 8 29 let bitsPerPixel = bitsPerComponent * 4 30 let bytesPerRow = bitsPerPixel * width / 8 31 32 let providerRef = CGDataProvider( 33 data: NSData(bytes: data, length: height * width * 4) 34 ) 35 36 let cgimage = CGImage( 37 width: width, 38 height: height, 39 bitsPerComponent: bitsPerComponent, 40 bitsPerPixel: bitsPerPixel, 41 bytesPerRow: bytesPerRow, 42 space: CGColorSpaceCreateDeviceRGB(), 43 bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue), 44 provider: providerRef!, 45 decode: nil, 46 shouldInterpolate: false, 47 intent: .defaultIntent 48 ) 49 return cgimage 50 } 51 52 func resize(image: UIImage, width: Double) -> UIImage { 53 54 let aspectScale = image.size.height / image.size.width 55 56 let resizedSize = CGSize(width: width, height: width * Double(aspectScale)) 57 print("height",width * Double(aspectScale)) 58 59 UIGraphicsBeginImageContext(resizedSize) 60 image.draw(in: CGRect(x: 0, y: 0, width: resizedSize.width, height: resizedSize.height)) 61 print("resizedSize.width",resizedSize.width) 62 let resizedImage = UIGraphicsGetImageFromCurrentImageContext() 63 UIGraphicsEndImageContext() 64 65 return resizedImage! 66 } 67

試したこと

スライダーの値によっては正常に動作するのですが、リサイズ後の画像のwidth×height×4と[Uint8]の配列の長さが一致しないことが多々あり、その場合に上手く画像が表示されません

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takabosoft

2019/09/12 05:27 編集

(回答したので質問取り下げます)
guest

回答1

0

ベストアンサー

let result_pix = RBGImage(data: katati_pixels, width: r22, height:r22)

let result_pix = RBGImage(data: katati_pixels, width: imageResize.cgImage!.width, height: imageResize.cgImage!.height)

にすれば動くかもしれません。


追記:

手元で再現しました。

配列からCGImageを作るときのbytesPerRowの値が元のCGImageと一致しないので、そこが原因だとは思いますが、
正しい計算式がちょっと調べた程度では出てこなかったので、こんな感じでごまかしました。

swift

1func RBGImage(data: [UInt8], compatible: CGImage) -> CGImage? { 2 let providerRef = CGDataProvider(data: NSData(bytes: data, length: data.count)) 3 let cgimage = CGImage( 4 width: compatible.width, 5 height: compatible.height, 6 bitsPerComponent: compatible.bitsPerComponent, 7 bitsPerPixel: compatible.bitsPerPixel, 8 bytesPerRow: compatible.bytesPerRow, 9 space: compatible.colorSpace!, 10 bitmapInfo: compatible.bitmapInfo, 11 provider: providerRef!, 12 decode: nil, 13 shouldInterpolate: false, 14 intent: .defaultIntent 15 ) 16 return cgimage 17 }

呼び出し方は
let result_pix = RBGImage(data: katati_pixels, compatible: imageResize.cgImage!)
でOKです。

投稿2019/09/12 04:39

編集2019/09/13 01:02
takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hkbto

2019/09/12 11:38

特に結果に差はありませんでした。。。 試してみた結果、rの値は「45,51,53,98,99,117,130」などで失敗しています。 成功した時の値は「100,136」などです。 失敗した例だと、RGBAが「0,0,0,0」となる値が配列に増えているみたいなのですが、何故増えているのかは全くわかっていないのが現状です。 また、読み込んでいる画像のサイズは196×196です。
takabosoft

2019/09/13 01:06

回答を追記しました。とりあえず手元では正しく出るようになりました。
hkbto

2019/09/14 11:26

解決しました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問