2017-02-14 13 views
2

私はMultibuttonを使って写真とその説明が掲載されたリストを表示しています。マルチボタン(コードネームワン)で丸められた画像(マスクを使用して)を作ることは可能ですか?

うまくいきますが、写真を丸くする必要があります。だから私はthe official guideのイメージマスキングに触発されたのです。残念ながら私が得るのは黒い丸です。

MultiButton[] cmps = new MultiButton[reports.size()]; 
for (int iter = 0; iter < reports.size(); iter++) { 
    Report currentReport = reports.get(iter); 
    if (currentReport == null) { 
     InfiniteScrollAdapter.addMoreComponents(this.getContentPane(), new Component[0], false); 
     return; 
    } 

    String photoFilenameInStorage = Report.getFilename(currentReport.getPhotoPath()); 
    Image reportImage = URLImage.createToStorage(placeholder, photoFilenameInStorage, currentReport.getPhotoPath(), URLImage.RESIZE_SCALE_TO_FILL); 
    int w = reportImage.getWidth(); 
    int h = reportImage.getHeight(); 

    // Generates a mask to make the image round 
    Image maskImage = Image.createImage(w, h, 0xff000000); 
    Graphics g = maskImage.getGraphics(); 
    g.setAntiAliased(true); 
    g.setColor(0xFFFFFF); 
    g.fillArc(0, 0, w, h, 0, 360); 

    Object mask = maskImage.createMask(); 

    Image maskedImage = reportImage.applyMask(mask); 

    String summary = currentReport.getLocation();       
    cmps[iter] = new MultiButton(summary); 
    // Only shows a black filled circle! 
    cmps[iter].setIcon(maskedImage); 
} 

InfiniteScrollAdapter.addMoreComponents(this.getContentPane(), cmps, true); 

私が気づいたことは、私はCN1で丸みを帯びた画像については見つけることができるすべての例は、Labelを扱っていることである:ここで私が使用したコードです。コードネーム1のMultiButtonにマスクを適用できますか?もしそうなら、どうしたらいいですか?

すべてのヘルプ感謝、

概要答えを読んだ後、私は私がしたが、ダイヤモンドの答え@仕事とないが、採掘なかった理由を把握するための苦労があった2017年2月16日

コメント丸い画像を得るためにマスキングに関する@ Shaiのガイドに従ってください。だから私はCN1の他の初心者がこの問題に遭遇した場合に、私の発見の結果を書きます。たくさんの助けになった彼の大きな説明のために@Diamondに再びThnaks!

まず、上記で紹介した丸いマスクは、黒い丸みが出ているので動作しています。実際マスクreportImageがまだフェッチしない限り、それはGUIによりために要求されるような画像を遅延フェッチされるデフォルトsince quoting from the javadoc

をダウンロードされていない適用される時間によって()メソッドは、その場合に呼び出されますIOコードは直ちに実行されます。

したがって、reportImageは、プレースホルダが定義されているのと同じくらい黒です。ところで、@Diamondはの円のプレースホルダーを定義して、実際の(丸い)画像が表示される前に素晴らしい色を表示するように提案しました(最初のcmps[iter].setIcon(placeholder)コールを参照)。

そしてInfiniteScrollAdapterニーズとは、フェッチするときURLImageにのみ、実際にダウンロードされます@Diamondは、上記のコードはInfiniteScrollAdapterで働くことができないという結論として、私はする傾向があるすべての私の試験の後

だから、ラップ、なぜimage.Thatさん私がしたいことを達成する唯一の方法は@Diamondが@ Shaiの提案で書いたコードだと考えてください。

ダウンロードされた画像がPNG @ Diamondの丸いマスクアダプターである場合、これ以上動作しないように見えることに注意してください。> PNGがJPEGとして変換された場合、画像は丸くなります。

答えて

2

はい、それは、マルチボタンのアイコンですが、あなたが

cmps[iter].getIconComponent() 

編集呼び出すことによって取得することができますLabelコンポーネントです:シャイさんのコメントに基づいて

を、あなたのコードは次のようになるはずです...

ラウンドマスクアダプタ:

private final URLImage.ImageAdapter RESIZE_SCALE_WITH_ROUND_MASK = new URLImage.ImageAdapter() { 
    @Override 
    public EncodedImage adaptImage(EncodedImage downloadedImage, EncodedImage placeholderImage) { 
     Image tmp = downloadedImage.scaledLargerRatio(placeholderImage.getWidth(), placeholderImage.getHeight()); 
     if (tmp.getWidth() > placeholderImage.getWidth()) { 
      int diff = tmp.getWidth() - placeholderImage.getWidth(); 
      int x = diff/2; 
      tmp = tmp.subImage(x, 0, placeholderImage.getWidth(), placeholderImage.getHeight(), true); 
     } else if (tmp.getHeight() > placeholderImage.getHeight()) { 
      int diff = tmp.getHeight() - placeholderImage.getHeight(); 
      int y = diff/2; 
      tmp = tmp.subImage(0, y, Math.min(placeholderImage.getWidth(), tmp.getWidth()), 
        Math.min(placeholderImage.getHeight(), tmp.getHeight()), true); 
     } 
     Image roundMask = Image.createImage(tmp.getWidth(), tmp.getHeight(), 0xff000000); 
     Graphics gr = roundMask.getGraphics(); 
     gr.setColor(0xffffff); 

     gr.fillArc(0, 0, tmp.getWidth(), tmp.getHeight(), 0, 360); 
     Object mask = roundMask.createMask(); 
     tmp = tmp.applyMask(mask); 
     return EncodedImage.createFromImage(tmp, false); 
    } 

    @Override 
    public boolean isAsyncAdapter() { 
     return true; 
    } 
}; 

コード改善:

//Placeholder image 

int size = Display.getInstance().convertToPixels(20); 
Image placeholder = Image.createImage(size, size, 0xbfc9d2); 
Graphics g = placeholder.getGraphics(); 
g.setAntiAliased(true); 
g.setColor(0xbfc9d2); 
g.fillArc(0, 0, size, size, 0, 360); 

MultiButton[] cmps = new MultiButton[reports.size()]; 
for (int iter = 0; iter < reports.size(); iter++) { 
    Report currentReport = reports.get(iter); 
    if (currentReport == null) { 
     InfiniteScrollAdapter.addMoreComponents(this.getContentPane(), new Component[0], false); 
     return; 
    } 

    String photoFilenameInStorage = Report.getFilename(currentReport.getPhotoPath()); 

    String summary = currentReport.getLocation(); 
    cmps[iter] = new MultiButton(summary); 
    // Only shows a black filled circle! 
    cmps[iter].setIcon(placeholder); 

    Display.getInstance().callSerially(() -> { 
     cmps[iter].setIcon(URLImage.createToStorage(cmps[iter].getIcon(), photoFilenameInStorage, currentReport.getPhotoPath(), RESIZE_SCALE_WITH_ROUND_CORNER_MASK)); 
     cmps[iter].getParent().revalidate(); 
    }); 
} 
InfiniteScrollAdapter.addMoreComponents(this.getContentPane(), cmps, true); 
+0

正しいです。また、あらかじめ(URLImageのように)画像を丸くする方が速くて、アプリのスタッターを少なくすることができます。 –

+0

ありがとう@ダイヤモンド!しかし、私はそれを働かせることができないので、私はより理解する必要があります。だから私はあなたのコードについていくつかの質問をするかもしれません:1)なぜ 'setIcon'を' getIconComponent'呼び出しの前に呼んでいますか? 2)さらに、 'callSerially'の中に' getIconComponent'をカプセル化する目的は何ですか。 3)そして最後になぜ 'revalidate'を呼び出しているのですが、' cmps'コンポーネントが追加されていませんか? – HelloWorld

+0

何がうまくいかないのかをより正確にするために、画像は丸みを帯びていない(しかし黒ではなく、すでに変更されている)のでマスクが機能しないと思います。私はそれをよりよく理解するためにコードに飛び込みます! – HelloWorld

関連する問題