Codenameone 如何在代号为1的图像顶部绘制?

Codenameone 如何在代号为1的图像顶部绘制?,codenameone,Codenameone,通过根据需要修改SignaturePanel类的定义,我成功地在整个屏幕上绘制了任意路径。接下来,我希望能够在用户选择的任何图片上进行绘制。基本上,图片应该保留在背景中,我应该能够操纵它。我尝试了可变映像,但不太明白如何实现它。如果能给我一些代码,我将不胜感激 以下是我到目前为止编写的代码: 主要类别:- package com.mycompany.myapp; import com.codename1.ui.Display; import com.codename1.ui.Form; im

通过根据需要修改SignaturePanel类的定义,我成功地在整个屏幕上绘制了任意路径。接下来,我希望能够在用户选择的任何图片上进行绘制。基本上,图片应该保留在背景中,我应该能够操纵它。我尝试了可变映像,但不太明白如何实现它。如果能给我一些代码,我将不胜感激

以下是我到目前为止编写的代码:

主要类别:-

package com.mycompany.myapp;


import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.Graphics;
import com.codename1.ui.Image;
import com.codename1.ui.Button;
import com.codename1.ui.Container;
import com.codename1.ui.Dialog;
import com.codename1.ui.Label;
import com.codename1.ui.Painter;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
import com.codename1.io.Log;
import com.codename1.io.MultipartRequest;
import com.codename1.ui.Toolbar;
import com.codename1.ui.URLImage;
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.geom.Rectangle;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.layouts.LayeredLayout;
import com.codename1.ui.painter.PainterChain;

import java.io.IOException;

/**
 * This file was generated by <a href="https://www.codenameone.com/">Codename One</a> for the purpose 
 * of building native mobile applications using Java.
 */
public class MainClass {

    private Form current;
    private Resources theme;

    SignaturePanel sp;

    public void init(Object context) {
        theme = UIManager.initFirstTheme("/theme");

        // Enable Toolbar on all Forms by default
        Toolbar.setGlobalToolbar(true);

        // Pro only feature, uncomment if you have a pro subscription
        // Log.bindCrashProtection(true);
    }

    public void start() {
        if(current != null){
            current.show();
            return;
        }
        Form hi = new Form("Hi World");
        hi.setLayout(new BorderLayout());

        Button browseGallery = new Button("Browse");

        Image test = Image.createImage(1280, 800, 0xffff00);
        hi.add(BorderLayout.NORTH,test);

        hi.addComponent(BorderLayout.SOUTH, browseGallery);
//        browseGallery.addActionListener(new ActionListener<ActionEvent>() {
//
//          @Override
//          public void actionPerformed(ActionEvent evt) {
//              Display.getInstance().openGallery(new ActionListener<ActionEvent>() {
//
//                  @Override
//                  public void actionPerformed(ActionEvent e) {
//                      
//                  }
//              }, Display.GALLERY_IMAGE);
//          }
//        }
        browseGallery.addActionListener(new ActionListener<ActionEvent>() {

            @Override
            public void actionPerformed(ActionEvent evt) {
                // TODO Auto-generated method stub
                Display.getInstance().openGallery(new ActionListener<ActionEvent>() {

                    @Override
                    public void actionPerformed(ActionEvent evt) {
                        // TODO Auto-generated method stub
                        try {

                            //Image mutable = Image.createImage(1280, 800, 0x00ff00);
                            //Image image = URLImage.createImage((String)evt.getSource());
                            //hi.add(BorderLayout.CENTER_BEHAVIOR_CENTER,mutable);
                            //image.modifyAlpha((byte) 10);

                        } catch (Exception e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        }
                    }
                }, Display.GALLERY_IMAGE);
            }
        });
//        hi.setGlassPane(new Painter() {
//          
//          @Override
//          public void paint(Graphics g, Rectangle rect) {
//              // TODO Auto-generated method stub
//              System.out.println("glasspane");
//          }
//      });

        sp = new SignaturePanel();
       // hi.getLayeredPane();
       // hi.add(LayeredLayout.encloseIn(new LayeredLayout(), sp);
        System.out.println("before adding");
        hi.addComponent(BorderLayout.CENTER, sp);
        System.out.println("after adding");
        hi.show();
    }

    public void stop() {
        current = Display.getInstance().getCurrent();
        if(current instanceof Dialog) {
            ((Dialog)current).dispose();
            current = Display.getInstance().getCurrent();
        }
    }

    public void destroy() {
    }

}

请忽略注释掉的代码

您可以在sp.getAllStyles.setBgImage()中将图像设置为组件的背景,然后像现在一样覆盖组件上的绘制(图形g)。然后,您应该将绘制形状的图像放在顶部。

FYI我们已经在Codename One中有一个签名组件,您也可以在此处检查其代码:是的,我从那里复制了代码,并根据需要修改了定义。这要容易得多@ShaiAlmog谢谢:)效果很好。谢谢@jamesan有没有办法让橡皮擦工作起来,这样在橡皮擦使用的路径上曝光图像之前,背景就可以了?
package com.mycompany.myapp;

import com.codename1.ui.Component;
import com.codename1.ui.Display;
import com.codename1.ui.Font;
import com.codename1.ui.Graphics;
import com.codename1.ui.Image;
import com.codename1.ui.Stroke;
import com.codename1.ui.geom.Dimension;
import com.codename1.ui.geom.GeneralPath;
import com.codename1.ui.geom.Rectangle;

class SignaturePanel extends Component {

    private final GeneralPath path = new GeneralPath();
    private final Stroke stroke = new Stroke();
    private final Rectangle signatureRect = new Rectangle();
    private final Font xFont;
    private Image value;

    SignaturePanel() {
        stroke.setLineWidth(Math.max(1, Display.getInstance().convertToPixels(1, true)/2));
        getAllStyles().setBgColor(0xffff00);
        getAllStyles().setBgTransparency(10);
        xFont = Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE);
    }

    /**
     * Overridden to try to make this component as sensitive as possible to 
     * drag events.  If we don't do this, it requires a longer drag before the "drag" 
     * events will kick in.
     * @param x
     * @param y
     * @return 
     */
    @Override
    protected int getDragRegionStatus(int x, int y) {
        return Component.DRAG_REGION_LIKELY_DRAG_XY;
    }

    /**
     * 
     * @param g 
     */
    @Override
    public void paint(Graphics g) {
        super.paint(g);

        g.setColor(0x666666);
        calcSignatureRect(signatureRect);
        g.drawRect(signatureRect.getX(), signatureRect.getY(), signatureRect.getWidth(), signatureRect.getHeight());
        g.drawString("X", signatureRect.getX() + Display.getInstance().convertToPixels(1, true), signatureRect.getY() + signatureRect.getHeight() / 2);
        paintSignature(g);
    }

    /**
     * Paints just the signature portion of the panel.  This is is reuised to
     * also create the image of the signature.
     * @param g 
     */
    private void paintSignature(Graphics g) {
        g.setColor(0x0);
        boolean oldAA = g.isAntiAliased();
        g.setAntiAliased(true);
        g.drawShape(path, stroke);
        g.setAntiAliased(oldAA);
    }

    /**
     * Calculates a rectangle (in parent component space) used for the drawn "rectangle" inside
     * which the user should draw their signature.  It tries to create a 16x9 rectangle that
     * fits inside the component with a bit of padding (3mm on each edge).
     * @param r Output variable.
     */
    private void calcSignatureRect(Rectangle r) {
        int w = getWidth() - Display.getInstance().convertToPixels(6, true);
        int h = (int)(w * 9.0 / 16.0);
        if (h > getHeight()) {
            h = getHeight() - Display.getInstance().convertToPixels(6, false);
            w = (int)(h * 16.0 / 9.0);
        }
        r.setX(getX() + (getWidth() - w) / 2);
        r.setY(getY() + (getHeight() - h)/2);
        r.setWidth(w);
        r.setHeight(h);
    }

    @Override
    protected Dimension calcPreferredSize() {
        Display d = Display.getInstance();
        return new Dimension(d.convertToPixels(100, true), d.convertToPixels(60, false));
    }

    @Override
    public void pointerPressed(int x, int y) {
        path.moveTo(x(x), y(y));

        value = null;
        repaint();
    }

    @Override
    public void pointerDragged(int x, int y) {
        path.lineTo(x(x), y(y));
        value = null;
        repaint();
    }

    @Override
    public void pointerReleased(int x, int y) {
        value = null;
        repaint();
    }

    /**
     * Converts an x coordinate from screen space, to parent component space.
     * @param x
     * @return 
     */
    private int x(int x) {
        return x - getParent().getAbsoluteX();
    }

    /**
     * Converts a y coordinate from screen space to parent component space.
     * @param y
     * @return 
     */
    private int y(int y) {
        return y - getParent().getAbsoluteY();
    }

    /**
     * Gets the currently drawn signature as an image.  This only includes the 
     * areas inside the {@link #signatureRect}
     * @return 
     */
    private Image getImage() {
        calcSignatureRect(signatureRect);

        Image img = Image.createImage(signatureRect.getWidth(), signatureRect.getHeight(), 0xffffff);
        Graphics g = img.getGraphics();
        g.translate(-signatureRect.getX(), -signatureRect.getY());
        paintSignature(g);
        return img;
    }

    /**
     * Resets the signature as a blank path.
     */
    private void clear() {
        path.reset();
    }
}