質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.50%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Q&A

解決済

2回答

369閲覧

特定ピクセルの色情報取得について

Y_M

総合スコア265

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

0グッド

0クリップ

投稿2017/12/26 02:10

編集2017/12/26 02:16

###前提・実現したいこと
最終的な目標としては、透明な部分には押された際の処理を実行しないような実装を行ないたいです。

そのためまずはUIButtonに対しhitTestをオーバライドし、タップされたピクセルのアルファ値を取得しようとしています。
しかしその際にpointの位置がずれているのか、透過部分でもアルファ値が1だったり、タップする場所によってはクラッシュします。

Thread 1: EXC_BAD_ACCESS(code=1, address+0x1048cb12c)

こちらの原因がわからないのでご相談しました。

###クラッシュする際の情報

Width =Optional(800) Height=Optional(444) BitsPerPixel=Optional(16) BytesPerRow=Optional(1600) BitsPerComponent=Optional(8) AlphaInfo=Optional(1) BitmapInfo=Optional(1) scale=2.0 point=(277.5, 377.0)

###該当のソースコード

swift

1import UIKit 2 3class TransparentButton: UIButton { 4 5 override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { 6 let pixelDataByteSize = 4 7 8 if let image = self.imageView?.image { 9 let imageData = image.cgImage?.dataProvider?.data 10 let data = CFDataGetBytePtr(imageData) 11 let scale = UIScreen.main.scale 12 let address: Int = ((Int(image.size.width) * Int(point.y * scale)) + Int(point.x * scale)) * pixelDataByteSize 13 14 15 print("Width =(String(describing: image.cgImage?.width))") 16 print("Height=(String(describing: image.cgImage?.height))") 17 print("BitsPerPixel=(String(describing: image.cgImage?.bitsPerPixel))") 18 print("BytesPerRow=(String(describing: image.cgImage?.bytesPerRow))") 19 print("BitsPerComponent=(String(describing: image.cgImage?.bitsPerComponent))") 20 print("AlphaInfo=(String(describing: image.cgImage?.alphaInfo.rawValue))") 21 print("BitmapInfo=(String(describing: image.cgImage?.bitmapInfo.rawValue))") 22 print("scale=((self.imageView?.image?.scale)!)") 23 print("point=(point)") 24 25 26 27 let r = CGFloat((data?[address])!) //Thread 1: EXC_BAD_ACCESS(code=1, address+0x1048cb12c) 28 let g = CGFloat((data?[address + 1])!) 29 let b = CGFloat((data?[address + 2])!) 30 let a = CGFloat((data?[address + 3])!) / 255.0 31 32 print(r, g, b, a) 33 34 } 35 36 return nil 37 } 38 39}

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

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

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

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

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

guest

回答2

0

自己解決

最終的にやりたいことが実装できるライブラリを見つけましたので解決とします。

OBShapedButton
UIButtonに設定した画像の、透過部分の判定をなくせるライブラリ。

投稿2017/12/26 03:54

Y_M

総合スコア265

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

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

0

BitsPerPixel=Optional(16)

1ピクセル = 16ビット = 2バイト

なのに、

let pixelDataByteSize = 4

で計算しているのが原因ではないかと。


ついでに、今回は問題になっていませんが、Y方向の計算部分は、

Int(image.size.width) * Int(point.y * scale)

ではなく、

BytesPerRow * point.y

が正しいです。(アンラップ/キャストは省略)

投稿2017/12/26 02:34

編集2017/12/26 02:36
fuzzball

総合スコア16731

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

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

Y_M

2017/12/26 02:51

取り急ぎは "let pixelDataByteSize = 2" にするべきと言うことでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問