2017-10-02 13 views
1

Goのimage.Imageインターフェイスには、Bounds(画像のサイズを決定するためにはっきりと必要)、At(各ピクセルで実際の色が返されます)、ColorModelという3つの方法があります。この最後のメソッドは、color.Modelを返します。これは、任意のモデルの色をこのイメージが使用する表現に変換することができます。image.ImageインターフェイスのColorModel()メソッドの目的は何ですか?

なぜColorModelがこのインターフェイスの一部ですか? image.Imageタイプの消費者はどのように使用していますか?私が画像imgを持っていて、その基礎となる表現について何も知らないのであれば、何が良いのですかimg.ColorModel()私は何をしますか?私は、任意の色を適切なモデルに変換することができますが、私はこの変換された色を何に使うことができないのか分かりません。イメージと対話する他の2つの方法であるAtBoundsは、引数として色を使用しません。

何か不足していますか?任意の標準ライブラリ関数がimage.ImageColorModelメソッドを呼び出していますか?

+0

に比べて、より効率的でしょうか? – JimB

+0

イメージがこの情報を提供しない場合は、どのようにカラーモデルを決定しますか? – Volker

+0

@JimB一般的に、イメージには色を設定できません。どのインタフェースメソッドも色の変更をサポートしておらず、すべての画像が変更可能な色の配列として格納されているわけではありません。 –

答えて

1

あなたの質問を完全に理解しているかどうか分かりませんが、ColorModel()の目的は色を変更することだとは思いません。カラーモデルを取得するだけです。 PNGパッケージのように、画像を符号化する際に

標準ライブラリは、主にそれを使用しています。

switch m.ColorModel() { 
case color.GrayModel: 
    e.cb = cbG8 
case color.Gray16Model: 
    e.cb = cbG16 
case color.RGBAModel, color.NRGBAModel, color.AlphaModel: 
    if opaque(m) { 
     e.cb = cbTC8 
    } else { 
     e.cb = cbTCA8 
    } 
default: 
    if opaque(m) { 
     e.cb = cbTC16 
    } else { 
     e.cb = cbTCA16 
    } 
} 
その上にもう一つのヒントは、使用目的は、JPEG /ライタで見つけることができます

// TODO(wathiede): switch on m.ColorModel() instead of type. 
+0

ありがとう!意味あり。私はあなたが色を返すと言っても間違いがあるように思えます。モデル、インターフェース、消費者が返されたオブジェクトを実際に定義された既存のオブジェクトのセットと実際に比較するとき。しかしGoの欠点(例えば、タグ付けされた共用体型)があれば、物事を整理する良い方法はないかもしれません。 –

+0

フォローアップをお願いします。なぜ、このメソッド(ColorModel()メソッドの戻り値を切り替える)は、 'At'メソッドによって返された色の型切り替えを使うよりも望ましいのでしょうか? –

+1

私は主な理由はスピードだと思います。タイプ切り替えが遅くなります。 単純なベンチマークの場合:https://play.golang.org/p/bocw3y9RHS また、ピクセルの色を最初に取得してから、そのタイプを確認する代わりに、ColorModelを直接取得するのがスタイリッシュな方がいいと思います。 どちらも動作します。 –

1

color.Modelは、色を異なる色の種類に変換することができますが、the docsでは:

インターフェイスColorModelには、画像のカラーモデルが記載されています。

つまり、ピクセルのカラーモデルではありません。類似していますが、後で画像に異なる色モデルのピクセルを含んでいる可能性があります。

imageは、均質な色の矩形グリッドを表します。つまり、すべてのピクセルが同じ色モデルを持っています。 のカラーモデルimageであることを理解したら、imageを特定の具体的な画像タイプにキャストしてから、その特定の画像を直接操作する方が効率的です。以下のスニペットは、アイデアを示しています

switch img.ColorModel() { 
case color.RGBAModel: 
    // Try to cast to RGBA first 
    m, ok := img.(*image.RGBA) 
    if !ok { 
     //not an RGBA image, do generic/custom processing, 
     //e.g. using interface exposed by image.Image 
     return 
    } 

    //Direct pixel access for performance 
    for y := m.Rect.Min.Y; y < m.Rect.Max.Y; y++ { 
     yp := (y - m.Rect.Min.Y) * m.Stride 
     for x := m.Rect.Min.X; x < m.Rect.Max.X; x++ { 
      rgba := m.Pix[yp+(x-m.Rect.Min.X)*4:] //[]byte{r, g, b, a} 
      //get rgba component 
      r, g, b, a := rgba[0], rgba[1], rgba[2], rgba[3] 

      //set r channel to RED 
      rgba[0] = 255 

      //...   
     } 
    } 
} 

は、以下のコードは、正しいモデルにあなたの色を変換することができなかった場合は、あなたのイメージに色を設定する方法を

// Less efficient image processing 
// a type-switch on the color returned by the `At` method 
b := img.Bounds() 
for y := b.Min.Y; y < b.Max.Y; y++ { 
    for x := b.Min.X; x < b.Max.X; x++ { 
     col := img.At(x, y) 
     switch col := col.(type) { 
     case color.RGBA: 
      //do something with pixel 
     } 
    } 
} 
+0

ありがとう!しかし、画像はRGBAカラーモデルをimage.RGBAなしに持つことができるので、私には奇妙なことです。私は、関数のグラフを表現し、ピクセル値の配列を含まない独自のイメージ型を実装しました。 'At'からRGBAカラーを返すので、カラーモデルはRGBAですが、タイプ強制をしようとする人は誰もが失望します。 (一般に、あなたの目標が型強制を行うことであるならば、それを行うだけで、それが動作するかどうかを確認するのはなぜですか?なぜカラーモデルを最初にチェックするのですか?) –

+0

'color.RGBAModel'を持つイメージは必ずしも'image.RGBA'。私の主なポイントは、 'At'メソッドで色を取得するたびに*ループの内側で**ループの外側で**タイプチェック**を行うことです。高いです。おそらく、小さな画像の場合、その差は目立たないが、大きな画像(3D/4D画像)を扱う場合、その違いがわかる。 RGB画像でない場合は、非効率なアクセスモードにいつでも切り替えることができます。私は私のコメントを反映するために答えを更新しました。 – putu

+0

ありがとうございます、あなたのポイントは十分に取られています! 「ColorModel」は実際にはこれを考慮していないようです。 'ColorModel'を使わずにループの外側で型の強制を行うことができます(効率的であれば、' ColorModel'への呼び出しは無関係で誤解を招く可能性があります)。 –

関連する問題