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

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

ただいまの
回答率

91.28%

  • Swift

    5287questions

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

Swift 戻り値を指定しているのに,戻り値がない旨のエラーが出る

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 94

maru.wk

score 21

Swiftに関する質問です。
戻り値のある関数を作成し,指定した型でreturnさせたのですが,Missing return in a function expected to return '[UInt8]'というエラーが出ます。いろいろいじってみたのですが,解決せず,どうすれば良いのかわかりません。

//各ピクセルからRGB情報を抽出し,配列として保存するクラス
class rgbArray {

        var width : Int
        var height : Int
        var pixelData : Data
        var bytesPerRow : Int
        let bytesPerPixel = 4

        init? (myImage: CGImage) {

            pixelData = myImage.dataProvider!.data! as Data
            width = myImage.width
            height = myImage.height
            bytesPerRow = myImage.bytesPerRow
            print(myImage.bitsPerPixel)

        }

        func getPixelColorFromUIImage(x: Int,y: Int) -> [UInt8] {

            let pixelInfo: Int = (Int(bytesPerRow) * y + x * 4)
            let r = Double(pixelData[pixelInfo])
            let g = Double(pixelData[pixelInfo+1])
            let b = Double(pixelData[pixelInfo+2])

            var rgb : [UInt8]
            rgb = [UInt8(r),UInt8(g),UInt8(b)]


            return rgb

        }

}


//入力画像から出力画像のRGB配列を作成するクラス
class Transformation {

    var outSizeX : Int
    var outSizeY : Int
    var theta2 : Double
    var tanTheta : Double
    var dIn : Double
    var fIn : Double
    var dOut : Double
    var fOut : Double
    var InCenterX : Double
    var InCenterY : Double
    var outCenterX : Double
    var outCenterY : Double
    var inputImage1 : CGImage


    init? (inputImage: CGImage, OutSizeX : Int, OutSizeY : Int, Theta2 : Double) {
        outSizeX = OutSizeX
        outSizeY = OutSizeY
        theta2 = Theta2
        tanTheta = tan(0.5*theta2*(Double.pi)/180)
        dIn = 0.5*sqrt(pow(Double(inputImage.width),2) + pow(Double(inputImage.height), 2))
        fIn = dIn / tanTheta
        dOut = 0.5*sqrt(pow(Double(outSizeX),2) + pow(Double(outSizeY), 2))
        fOut = 2*dOut / M_PI
        inputImage1 = inputImage
        InCenterX = 0.5*Double(inputImage.width)
        InCenterY = 0.5*Double(inputImage.height)
        outCenterX = 0.5*Double(outSizeX)
        outCenterY = 0.5*Double(outSizeY)
        }
    //出力画像のRGB配列を作成する関数
    func createRGB() -> [UInt8]{

        var yOutX : Double
        var yOutY : Double
        var yOut : Double
        var inPixelI : Int
        var inPixelJ : Int
        var yIn : Double
        var scale : Double

        //全ピクセルに対して処理を行う
        for y in 0..<outSizeY{
            for x in 0..<outSizeX{

              //出力画像の中心座標から任意のピクセルまでの距離
              yOutX = Double(x) - outCenterX + 0.5
              yOutY = Double(y) - outCenterY + 0.5
              yOut = sqrt(pow(yOutX,2) + pow(yOutY,2))

              //rgbArrayをインスタンス化し,outputRGBに出力画像の任意のピクセルのRGB情報を格納
                var outputRGB = rgbArray(myImage: inputImage1)?.getPixelColorFromUIImage(x: x, y: y)

              //yOutの値から,条件分岐
              if yOut == 0 {
              inPixelI = Int(round(InCenterX-0.5))
              inPixelJ = Int(round(InCenterY-0.5))
              //求めた入力画像の座標におけるピクセルのRGB情報を,出力画像のピクセルのRGB情報に上書き
              let centerInputRGB = rgbArray(myImage: inputImage1)?.getPixelColorFromUIImage(x: inPixelI, y: inPixelJ)
              outputRGB?[0] = (centerInputRGB?[0])!
              outputRGB?[1] = (centerInputRGB?[1])!
              outputRGB?[2] = (centerInputRGB?[2])!

              }else {
              //射影変換を行い,出力画像でのyOutが入力画像ではどのような値になるか調べる
              yIn = fIn*tan(yOut/fOut)
              scale = yIn / yOut
              //yInから,出力画像の任意のピクセルに対応する,入力画像のピクセルの座標を調べる
              inPixelI = Int(round(yOutX*scale + InCenterX - 0.5))
              inPixelJ = Int(round(yOutY*scale + InCenterY - 0.5))
              //入力画像のピクセルのRGB情報を得る
              let inputRGB = rgbArray(myImage: inputImage1)?.getPixelColorFromUIImage(x: inPixelI, y: inPixelJ)

              if (inPixelI < Int(inputImage1.width)) && (inPixelJ < Int(inputImage1.height)) {
                  outputRGB?[0] = (inputRGB?[0])!
                  outputRGB?[1] = (inputRGB?[1])!
                  outputRGB?[2] = (inputRGB?[2])!
              }else {
                  outputRGB?[0] = 0
                  outputRGB?[1] = 0
                  outputRGB?[2] = 0
                     }
                   }

              return (outputRGB)!
                 }
            }
    }

エラーが出るのは最後の,return (outputRGB)!の所です。まだまだSwiftに不慣れで雑なコードになっておりますが,どなたかよろしくお願い致します。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+2

outSizeXやoutSizeYが0のときにreturn (outputRGB)!が実行されません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/13 10:49

    ご回答ありがとうございます。つまりは,outSizeXやoutSizaYが0でないことを何かしらで保証すれば良い,という解釈であっておりますでしょうか?

    キャンセル

  • 2017/12/13 11:09

    「保証」というのが具体的にどういうことなのか分かりませんが、outSizeXやoutSizaYが0のときでも何らかの値を返さないといけません。createRGB() は、どんな場合でも [UInt8] を返さないといけないんです。

    例えば return [] でカラ配列を返すとかです。

    キャンセル

  • 2017/12/13 12:02

    理解が追いつかず,申し訳ありません。outSizeXとoutSizeYが0でも[Uint8]を返す必要があるが,0だと[Uint8]配列を返すことができないため,エラーが起きる,ということであれば,outSizeXやoutSizeYにあらかじめ何かしらの値を与えておけば,エラーは出ないと解釈したのですが,あってますでしょうか?

    キャンセル

  • 2017/12/13 12:02

    何度も申し訳ありません

    キャンセル

  • 2017/12/13 12:36

    >>0だと[Uint8]配列を返すことができないため,エラーが起きる
    違います。「返すことができない」からではなく「返していない」からエラーが出ているのです。

    >>outSizeXやoutSizeYにあらかじめ何かしらの値を与えておけば
    というのは実行時の話です。ビルドエラーなのですから、ビルドが通るように修正しないといけません。

    キャンセル

checkベストアンサー

0

for文を二回かいたネスト構造で、さらにコードが長く可読性がかなり悪いのでこのようなことになっているかと思われます。

もう少し簡単にかくとこのような感じではないでしょうか

func test() -> [Int] {
        var i = 0
        if i == 0 {
            var outSize: [Int]
            if i == 0 {

            }
            return outSize
        }
    }

このメソッド(test())の問題として、if文という条件式の中でしか、返り値を設定しておらず、条件式を通過しない場合の返り値が考慮されていません。そのためエラーが出ます。

なの最後に以下のように付け加えれば直るのではないでしょうか?

func test() -> [Int] {
        var i = 0
        if i == 0 {
            var outSize: [Int]
            if i == 0 {

            }
            return outSize
        }
        return [0]
    }

今自分があげたような構造とほぼ同じような形になっているかと思うので確認してみてください。
基本的にコードが長くなったらメソッドで切り出してあげたほうがいいかと。
参考にならなかったら無視しちゃって大丈夫ですw

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/04 11:42

    返答が大変遅くなり申し訳ありません。
    このようなやり方があるのですね!
    今から試してみます。丁寧なご解説ありがとうございます。

    キャンセル

  • 2018/01/07 16:14

    おかげさまで解決することができました。
    if文の中のみの戻り値では不完全なのですね!
    基本的なことで失礼いたしました。ありがとうございました。

    キャンセル

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

ただいまの回答率

91.28%

関連した質問

同じタグがついた質問を見る

  • Swift

    5287questions

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