2017-07-25 63 views
1

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

这里是我已经编写了这么远:

主要类别: -

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() { 
    } 

} 

SignaturePanel: -

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

请忽略注释掉的代码

+0

仅供参考我们在Codename One中已经有了一个签名组件,您也可以在这里检查它的代码:https://github.com/codenameone/CodenameOne/blob/master/CodenameOne/src/com/codename1/components/SignatureComponent。 java –

+0

是的,我从那里复制了代码并根据需要修改了定义。这很容易@ShaiAlmog谢谢:) – Gurankas

回答

1

可以设置将图像作为组件的背景,如sp.getAllStyles.setBgImage(),然后重写根据您现在的组件绘制(图形g)。然后,您应该将图形放在顶部。

+0

工作就像一个魅力。谢谢@詹姆斯 – Gurankas

+0

任何想法如何使橡皮擦工作,使图像之前的背景曝光在橡皮擦使用的路径? – Gurankas