2017-08-01 19 views
1

私は、ユーザーが定義した閉じた自由なパス(開始点と終了点を結んで閉じている)で設定イメージを切り抜くマイナークロップ画像アプリケーションを作成しました。このアプリは、異なるパスの方向(時計回りと反時計回り)でトリミングするときの異常な動作を示しています。誰もがなぜこれが起きているのか、この問題を解決する方法を説明できますか?CodenameOneの異常なCrop/GeneralPathの動作

私自身の定義されたGeneralPathのクラス

package com.mycompany.myapp; 

import com.codename1.charts.util.ColorUtil; 
import com.codename1.ui.Component; 
import com.codename1.ui.Display; 
import com.codename1.ui.Graphics; 
import com.codename1.ui.Stroke; 

public class GeneralPath extends Component{ 

    com.codename1.ui.geom.GeneralPath generalPath; 
    Stroke stroke = new Stroke(); 
    int firstPointX = 0, firstpointY = 0; 
    MyApplication myApplication; 

    public GeneralPath(MyApplication application) { 
     // TODO Auto-generated constructor stub 
     generalPath = new com.codename1.ui.geom.GeneralPath(); 
     stroke.setLineWidth(Math.max(1, Display.getInstance().convertToPixels(1, true)/2)); 
     getAllStyles().setBgColor(0xffffff); 
     getAllStyles().setBgTransparency(200); 
     myApplication = application; 
    } 
    @Override 
    public void paint(Graphics g) { 
     // TODO Auto-generated method stub 
     super.paint(g); 
     paintDrawing(g); 
    } 
    private void paintDrawing(Graphics g) 
    { 
     g.setColor(ColorUtil.argb(0, 255, 255, 255)); 
     boolean oldAA = g.isAntiAliased(); 
     g.setAntiAliased(true); 
     g.drawShape(generalPath, stroke); 
     g.setAntiAliased(oldAA); 
    } 
    @Override 
    public void pointerPressed(int a, int b) { 
     firstPointX = a; 
     firstpointY = b; 
     generalPath.moveTo(x(a), y(b)); 
    } 
    @Override 
    public void pointerDragged(int a, int b) { 
     generalPath.lineTo(x(a), y(b)); 
    } 
    @Override 
    public void pointerReleased(int x, int y) { 
     generalPath.lineTo(x(firstPointX), y(firstpointY)); 
     myApplication.clip(); 
    } 
    public int x(int x) 
    { 
     return x-getParent().getAbsoluteX(); 
    } 
    public int y(int y) 
    { 
     return y - getParent().getAbsoluteY(); 
    } 
    public com.codename1.ui.geom.GeneralPath getPath() 
    { 
     return generalPath; 
    } 
} 

MyApplication.java(メインクラス)

package com.mycompany.myapp; 

import com.codename1.io.Log; 
import com.codename1.ui.Button; 
import com.codename1.ui.Display; 
import com.codename1.ui.FontImage; 
import com.codename1.ui.Form; 
import com.codename1.ui.Graphics; 
import com.codename1.ui.Image; 
import com.codename1.ui.Dialog; 
import com.codename1.ui.Label; 
import com.codename1.ui.Stroke; 
import com.codename1.ui.animations.CommonTransitions; 
import com.codename1.ui.geom.GeneralPath; 
import com.codename1.ui.layouts.BorderLayout; 
import com.codename1.ui.layouts.BoxLayout; 
import com.codename1.ui.layouts.FlowLayout; 
import com.codename1.ui.layouts.LayeredLayout; 
import com.codename1.ui.plaf.UIManager; 
import com.codename1.ui.util.Resources; 
import com.codename1.ui.util.UITimer; 
import java.io.IOException; 
import com.codename1.ui.Toolbar; 
import com.codename1.ui.geom.Rectangle; 

/** 
* 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 MyApplication { 

    private Form current; 
    private Resources theme; 

    Form hi; 
    com.mycompany.myapp.GeneralPath gp; 
    Image finalDuke; 


    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("Welcome", new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE)); 
//  final Label apple = new Label(theme.getImage("apple-icon.png")); 
//  final Label android = new Label(theme.getImage("android-icon.png")); 
//  final Label windows = new Label(theme.getImage("windows-icon.png")); 
//  Button getStarted = new Button("Let's Get Started!"); 
//  FontImage.setMaterialIcon(getStarted, FontImage.MATERIAL_LINK); 
//  getStarted.setUIID("GetStarted"); 
//  hi.addComponent(BorderLayout.CENTER, 
//    LayeredLayout.encloseIn(
//      BoxLayout.encloseY(
//        new Label(theme.getImage("duke-no-logos.png")), 
//        getStarted 
//      ), 
//      FlowLayout.encloseRightMiddle(apple) 
//     ) 
//  ); 
//   
//  getStarted.addActionListener((e) -> { 
//   Display.getInstance().execute("https://www.codenameone.com/developers.html"); 
//  }); 
//   
//  new UITimer(() -> { 
//   if(apple.getParent() != null) { 
//    apple.getParent().replace(apple, android, CommonTransitions.createFade(500)); 
//   } else { 
//    if(android.getParent() != null) { 
//     android.getParent().replace(android, windows, CommonTransitions.createFade(500)); 
//    } else { 
//     windows.getParent().replace(windows, apple, CommonTransitions.createFade(500)); 
//    }     
//   } 
//  }).schedule(2200, true, hi); 

     Image duke = null; 
     try { 
      // duke.png is just the default Codename One icon copied into place 
      duke = theme.getImage("promo_5.png"); 
     } catch(Exception err) { 
      Log.e(err); 
     } 
     finalDuke = duke; 

     hi = new Form("Shape Clip", new BorderLayout()); 

     // We create a 50 x 100 shape, this is arbitrary since we can scale it easily 
//  GeneralPath path = new GeneralPath(); 
//  path.moveTo(20,0); 
//  path.lineTo(30, 0); 
//  path.lineTo(30, 100); 
//  path.lineTo(20, 100); 
//  path.lineTo(20, 15); 
//  path.lineTo(5, 40); 
//  path.lineTo(5, 25); 
//  path.lineTo(20,0); 

     gp = new com.mycompany.myapp.GeneralPath(this); 
     hi.add(BorderLayout.CENTER,gp); 
     hi.getLayeredPane().add(finalDuke); 



     hi.show(); 
    } 

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

    public void destroy() { 
    } 
    public void clip() 
    { 
     Stroke stroke = new Stroke(0.5f, Stroke.CAP_ROUND, Stroke.JOIN_ROUND, 4); 
//  hi.getContentPane().getUnselectedStyle().setBgPainter((Graphics g, Rectangle rect) -> { 
//   g.setColor(0xff0000); 
//   float widthRatio = ((float)rect.getWidth())/50f; 
//   float heightRatio = ((float)rect.getHeight())/100f; 
//   g.scale(widthRatio, heightRatio); 
//   g.translate((int)(((float)rect.getX())/widthRatio), (int)(((float)rect.getY())/heightRatio)); 
//   g.setClip(gp.getPath()); 
//   g.setAntiAliased(true); 
//   g.drawImage(finalDuke, 0, 0, 50, 100); 
//   g.setClip(gp.getPath().getBounds()); 
//   g.drawShape(gp.getPath(), stroke); 
//   g.translate(-(int)(((float)rect.getX())/widthRatio), -(int)(((float)rect.getY())/heightRatio)); 
//   g.resetAffine(); 
//  }); 

     hi.getContentPane().getAllStyles().setBgPainter((Graphics g, Rectangle rect) -> { 
      g.drawShape(gp.getPath(), stroke); 
      g.setClip(gp.getPath()); 
      Image image = finalDuke; 
      g.drawImage(image, 0, 0); 
     }); 

    } 
} 

コメントアウト部分を無視してください - :

次のコードです。あなた

スクリーンショットありがとう: -

3オーバーラップ矩形が作物中に絵を反転しませんが、矩形にその逆方向の三角形の形状が逆前回のパスをカットし

Example 2

+0

これはどのように表示されるか説明するための例示的なスクリーンショットを提供できますか? –

+0

@ShaiAlmogは説明付きのスクリーンショットをいくつか更新しました – Gurankas

答えて

1

pointerReleasedでclosePath()を呼び出してみてください。ユーザーがでもほぼのパスを手動で閉じると、実際には閉じられない可能性があります。クローズされていないシェイプをクリップシェイプとして使用しようとすると、予期しない結果が発生します。

+0

GeneralPathクラスのpointerReleased()メソッドで解放されたポインタと解放されたポインタの座標を結合するので、決して閉じられていないシェイプではありません – Gurankas

+0

closePathを上記のコードは、あなたが試みたことを意味しますか? –

+0

@ShaiAlmog正しいです – Gurankas

関連する問題