是否可以在多按钮(代号一)上使图像变圆(通过蒙版) [英] Is it possible to make rounded image (via mask) on Multibutton (Codename One)

查看:40
本文介绍了是否可以在多按钮(代号一)上使图像变圆(通过蒙版)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 InfiniteScrollAdapter ,其中使用 Multibutton 显示包含照片及其描述的列表。 / p>

效果很好,但我需要对照片进行四舍五入。这就是为什么我受到图片遮罩的官方指南的启发。不幸的是,我得到的只是一个黑色的回合。这是我使用的代码:

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

字符串photoFilenameInStorage = Report.getFilename(currentReport.getPhotoPath());
图片reportImage = URLImage.createToStorage(占位符,photoFilenameInStorage,currentReport.getPhotoPath(),URLImage.RESIZE_SCALE_TO_FILL);
int w = reportImage.getWidth();
int h = reportImage.getHeight();

//生成蒙版以使图像变圆
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);

对象mask = maskImage.createMask();

图像maskedImage = reportImage.applyMask(mask);

字符串摘要= currentReport.getLocation();
cmps [iter] =新的MultiButton(摘要);
//仅显示黑色实心圆圈!
cmps [iter] .setIcon(maskedImage);
}

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

我注意到的是,我能找到的所有关于CN1中舍入图像的示例都用标签。是否可以在代号为One的 MultiButton 上应用遮罩?如果是这样,我该怎么做?



任何帮助表示赞赏,



阅读本书后的摘要答案和评论2017-02-16



尽管我确实关注@Shai的问题,但我很难弄清楚@Diamond的答案为什么行得通而不是我的?遮罩指南以获取圆形图像。因此,我写出我的发现的结果,以防CN1的其他新手遇到此问题。再次感谢@Diamond的出色解释,这对我们大有帮助!



首先,上面介绍的圆形口罩有效,因为它会产生黑色的圆形。确实,在应用蒙版时,尚未下载 reportImage 因为引用了Javadoc


默认情况下会提取图像除非被调用fetch()方法,否则GUI会很懒惰,除非在这种情况下立即执行IO代码。


因此, reportImage 仍然与占位符所定义的一样黑。顺便说一句,这就是为什么@Diamond建议定义一个圆形占位符,并在实际(圆形)图像可用之前显示一种漂亮的颜色(请参阅第一个 cmps [iter ] .setIcon(placeholder)调用他的答案)。



URLImage仅在时才实际下载InfiniteScrollAdapter 需要并获取图像。这就是@Diamond包装



的原因,因此,以上代码不能在 InfiniteScrollAdapter ,经过所有的尝试,我倾向于认为实现我想要做的唯一方法是@Diamond在@Shai的建议下编写的代码。



请注意,如果下载的图片是PNG,@ Diamond的圆形蒙版适配器似乎不再起作用=>仅当PNG转换为JPEG

解决方案

是的,多按钮图标是一个Label组件,您可以通过调用来获取

  cmps [iter] .getIconComponent()

编辑:



根据Shai的评论,您的代码应变成这样……



圆形蒙版适配器:

 私有最终URLImage.ImageAdapter RESIZE_SCALE_WITH_ROUND_MASK =新的URLImage 。 
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);
}否则,如果(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() ),是);
}
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);
对象遮罩= roundMask.createMask();
tmp = tmp.applyMask(掩码);
返回EncodedImage.createFromImage(tmp,false);
}

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

代码改进:

  //占位符图像

int size = Display.getInstance()。convertToPixels(20);
图片占位符= 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 ++){
报告currentReport = reports.get(iter);
if(currentReport == null){
InfiniteScrollAdapter.addMoreComponents(this.getContentPane(),new Component [0],false);
的回报;
}

字符串photoFilenameInStorage = Report.getFilename(currentReport.getPhotoPath());

字符串摘要= currentReport.getLocation();
cmps [iter] =新的MultiButton(摘要);
//仅显示黑色实心圆圈!
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);


I have an InfiniteScrollAdapter in which I use Multibutton to display a list featuring a photo and its description.

It works well but I need to make the photo rounded. That's why I got inspired by the official guide on image masking. Unfortunately what I get is only a black round. Here is the code I used:

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);

What I've noticed is that all examples I could find about the rounded image in CN1 dealt with Label. Is it possible to apply a mask on a MultiButton in Codename One? If so, how can I do that?

Any help appreciated,

Summary after reading the answers and comments 2017-02-16

I have had hard time to figure out why @Diamond's answer did work and not mine although I did follow @Shai's guide on masking to get rounded images. So I write the outcome of my findings in case other newbies at CN1 came across this issue. Thnaks again to @Diamond for his great explanations that helped a lot!

First of all, the round mask introduced above is working since it yields a black round. Indeed by the time where the mask is applied the reportImage has not been downloaded yet since quoting from the javadoc

By default an image is fetched lazily as it is asked for by the GUI unless the fetch() method is invoked in which case the IO code is executed immediately.

Consequently reportImage is still as black as the placeholder was defined. By the way this is why @Diamond suggested to define a round placeholder with a nice color to be shown before the actual (round) image gets available (see the first cmps[iter].setIcon(placeholder) call in his answer).

And the URLImage will only be actually downloaded when the InfiniteScrollAdapter needs and fetches the image.That's why @Diamond wraps

So as a conclusion the code above cannot work in an InfiniteScrollAdapter and after all my trials I tend to think that the only way to achieve what I wanted to do is the code @Diamond wrote with @Shai's suggestion.

Please note that with if the downloaded picture is a PNG @Diamond's round mask adapter does not seem to work anymore => the resulting image is only rounded if the PNG is converted as JPEG.

解决方案

Yes it is, Multibutton icon is a Label component which you can get by calling

cmps[iter].getIconComponent()

Edit:

Based on Shai's comment, your code should become something like this...

Round Mask Adapter:

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;
    }
};

Code Improvement:

//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);

这篇关于是否可以在多按钮(代号一)上使图像变圆(通过蒙版)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆