web-dev-qa-db-ja.com

android-画像ビュー内の画像のエッジx / y位置を取得する方法

画面いっぱいのImageViewがある場合。
ImageViewの背景が緑色に設定されています。
ビットマップの比率を維持しながら、ImageViewにビットマップを配置します。

このレイアウトのポートレート写真は、左側と右側の両方に緑色で表示されます
(電話の向き=ポートレート)。

ここで、グリーンが終了してビットマップが開始したときに、エッジの左側のx/y位置を取得する方法を教えてください。

この取り組みプロジェクトの背景は、画像にテキストを書き込んで、テキストを含む新しい画像に画像を保存することです。問題は..

私は画像をSampleSize = 4でスケーリングしているので、 ImageViewはさらに縮小し、この新しい画像を保存すると、約250x350の小さな画像になります。

私が欲しいのは、x/y位置を使用して、書き込まれたテキストを元のinSampleSize = 4画像またはsdcard 1500x3000画像に転送することです

私は自分自身で「数学の計算を行う」必要があるという他の質問を知って読んでいます。この小さな答えが必要です。

明確にするためにスクリーンショットを撮ることができないのを忘れました。

これは次のようになります(「ペン」ボタンを押すと新しいペンが表示されます。各ペンは画面上で独自のテキストと位置を保持しています。

enter image description here

これがimageviewです

    import Java.util.HashMap;
    import Java.util.UUID;
    import Android.app.Activity;
    import Android.content.Context;
    import Android.graphics.Bitmap;
    import Android.graphics.BitmapFactory;
    import Android.graphics.Canvas;
    import Android.graphics.Color;
    import Android.graphics.Paint;
    import Android.graphics.Point;
    import Android.graphics.Rect;
    import Android.graphics.Typeface;
    import Android.graphics.drawable.BitmapDrawable;
    import Android.graphics.drawable.Drawable;
    import Android.os.Environment;
    import Android.util.AttributeSet;
    import Android.view.Display;
    import Android.view.MotionEvent;
    import Android.widget.EditText;
    import Android.widget.ImageView;

    public class DrawView2 extends ImageView {

        private HashMap<String, ColorBall2> HashBall ;
        private String balID = ""; // variable to know what ball is being dragged
        public final String PTPPSERVICE_DERECTORY = "/PTPPservice/";    
        private Bitmap bitmap;
        private EditText ed;
        private Paint paint = new Paint();
        private Paint paint2 = new Paint();
        private Paint pTouch = new Paint();
        private EditText addtext;
        private Context ctx;
        private String imagePath;
        private boolean removeBall = false;
      int viewWidth = 0;
        int viewHeight = 0;
        double bitmapHight =0;
        double bitmapWidth =0;  
        double ratio =0;

        double startX = 0;
        double endX= 0;
        double startY= 0;
        double endY = 0;

        public DrawView2(Context context, AttributeSet atts,String image1) {

            super(context, atts);
            this.ctx = context;
            this.imagePath = image1;
            setFocusable(true);

            Paint.setStyle(Paint.Style.FILL_AND_STROKE);
            Paint.setColor(Color.BLACK);
            Paint.setTypeface(Typeface.DEFAULT_BOLD); 

            Paint2.setStyle(Paint.Style.FILL_AND_STROKE);
            Paint2.setColor(Color.RED);

          addtext = (EditText) ((Activity) ctx).findViewById(R.id.edittextaddtext); 

            String filePath = Environment.getExternalStorageDirectory().toString() + imagePath;
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 4;

            bitmap = BitmapFactory.decodeFile(filePath,options);
            // SAVE RATIO
            int x = bitmap.getWidth();
            int y = bitmap.getHeight();
            if(y>x)
                ratio = ((double)y)/x;
            if(x>y)
                ratio = ((double)x)/y;  
            if(y==x)
                ratio = 1;
            Drawable bit = new BitmapDrawable(bitmap);
            setImageDrawable(bit);

        }
        public double getRatio() {
            return ratio;
        }
        public HashMap<String, ColorBall2> getHashBall() {
            return HashBall;
        }
        // RETURN THE ON SCREEN RESIZED BITMAP
        public double getOnScreenBitmapHight(){

            return bitmapHight;
        }
        public double getOnScreenBitmapWidth(){

            return  bitmapWidth;
        }
        // BITMAP SIZE
        public int getBitmapHight(){

            return bitmap.getHeight();
        }
        public int getBitmapWidth(){

            return  bitmap.getWidth();
        }
        // GET IMAGEVIEW HIGHT WIDTH
        public int getViewWidth() {
            return viewWidth;
        }
        public int getViewHeight() {
            return viewHeight;
        }
        // START END X Y
        public double getStartX() {
            return startX;
        }
        public double getEndX() {
            return endX;
        }
        public double getStartY() {
            return startY;
        }
        public double getEndY() {
            return endY;
        }
        // SET BALL TEXT
        public void addTextToBall(String text) {
            if(balID != "")
            HashBall.get(balID).setText(text);
        }
        // PATH
        public String getImagePath() {
            return imagePath;
        }
        // THE ORIGINAL INSAMPELSIZE=4 BITMAP
        public Bitmap getBitmap() {
            return bitmap;
        }
        // STOP DRAWAING THE BALL
        public void removeBall(boolean value) {
           removeBall = value;      
        }   
        // THE RECT THAT RETURN WRONG VALUE
        public Rect getRect(){

            Rect r = getDrawable().copyBounds();

            int drawLeft = r.left;
            int drawTop = r.top;
            int drawRight = r.right;
            int drawBottom = r.bottom;
            return r;
        }

        @Override
        protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld){
            super.onSizeChanged(xNew, yNew, xOld, yOld);
            viewWidth = xNew;
            viewHeight = yNew;
        }

        public void addBall(){

// HERE I TRY TO CALCULATE THE BOUNDS LEFT,RIGHT,TOP AND BOTTOM Edge OF THE BITMAP
//NOT GOING THAT GOOD
            if(HashBall == null)
                HashBall = new HashMap<String,ColorBall2>();

            //X
            double drawAbleWidth = viewWidth/ratio;
            startX = (viewWidth-drawAbleWidth)/2;

            double drawAbleHight = viewHeight/ratio;
            startY = drawAbleHight/2;

            int ballY = (viewHeight/2); 
            int ballX = (viewWidth/2);

            Point point1 = new Point();
            point1.x = (int) ballX;
            point1.y = (int) ballY;
            String uuId = UUID.randomUUID().toString();
            HashBall.put(uuId,(new ColorBall2(ctx,R.drawable.pen1, point1,uuId)));  


        }

        @Override 
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);


            //canvas.drawCircle(10,10,10,null);
            if(!removeBall && HashBall != null){
                for (String key : HashBall.keySet()) {
                    //System.out.println("Key: " + key + ", Value: " + map.get(key));
                    if(addtext!=null)
                        //canvas.drawCircle(HashBall.get(key).getX(),      HashBall.get(key).getY(), 10, Paint2);
                        canvas.drawBitmap(HashBall.get(key).getBitmap(), HashBall.get(key).getX()-10, HashBall.get(key).getY()-80, null);
                      canvas.drawText  (HashBall.get(key).getText() + "  X="+HashBall.get(key).getX() + "  Y="+HashBall.get(key).getY()
                                , HashBall.get(key).getX(), HashBall.get(key).getY(), Paint);
                }

            }

        }


        // events when touching the screen
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            int eventaction = event.getAction(); 


            int X = (int)event.getX(); 
            int Y = (int)event.getY(); 

            switch (eventaction ) 
            { 

            case MotionEvent.ACTION_DOWN: // touch down so check if the finger is on a ball
                balID = "";
                for (String key : HashBall.keySet()) {

                    // check if inside the bounds of the ball (circle)
                    // get the center for the ball
                    int centerX = HashBall.get(key).getX() + 15;
                    int centerY = HashBall.get(key).getY() + 15;

                    // calculate the radius from the touch to the center of the ball
                    double radCircle  = Math.sqrt( (((centerX-X)*(centerX-X)) + (centerY-Y)*(centerY-Y)));

                    // if the radius is smaller then 23 (radius of a ball is 22), then it must be on the ball
                    if (radCircle < 33){
                        balID = HashBall.get(key).getID();
                        addtext.setText(HashBall.get(key).getText());
                        break;
                    }
                }

                break; 


            case MotionEvent.ACTION_MOVE:   // touch drag with the ball
                // move the balls the same as the finger
                if (balID != "") {
                    HashBall.get(balID).setX(X-25);
                    HashBall.get(balID).setY(Y-25);

                }
                break; 

            case MotionEvent.ACTION_UP: 
                // touch drop - just do things here after dropping

                break; 
            } 
            // redraw the canvas
            invalidate(); 
            return true; 
        }
    }
19
Erik

比率がわかっている場合は、画像の横に配置されるマージンの幅を導き出すことができます。

// These holds the ratios for the ImageView and the bitmap
double bitmapRatio  = ((double)bitmap.getWidth())/bitmap.getHeight()
double imageViewRatio  = ((double)imageView.getWidth())/imageView.getHeight()

これで、bitmapRatioがimageViewRatioより大きい場合、ビットマップの高さが等しい場合、ビットマップがimageviewよりも広いことを意味します。つまり、上部と下部に空白があります。

逆に、bitmapRatioがimageViewRatioよりも小さい場合は、左右に空白ができます。これから、0になるので、かなり簡単に座標の1つを取得できます。

if(bitmapRatio > imageViewRatio)
{
  drawLeft = 0;
}
else
{
  drawTop = 0;
}

他の座標を取得するには、左と右にスペースがある2番目のケースを考えてください。ここでは、ビットマップとimageViewの高さが等しいため、幅間の比率は比率間の比率に等しくなります。 imageViewの幅がわかっているので、これを使用してビットマップの幅を把握できます。同様に、幅が等しい場合は高さを計算できます。ただし、幅は比率に反比例するため、比率間の比率の逆数を使用する必要があります。

if(bitmapRatio > imageViewRatio)
{
  drawLeft = 0;
  drawHeight = (imageViewRatio/bitmapRatio) * imageView.getHeight();
}
else
{
  drawTop = 0;
  drawWidth = (bitmapRatio/imageViewRatio) * imageView.getWidth();
}

ビットマップの幅または高さを取得したら、横のスペースを取得するのは簡単です。これは、ビットマップとimageViewの幅または高さの違いの半分です。

if(bitmapRatio > imageViewRatio)
{
  drawLeft = 0;
  drawHeight = (imageViewRatio/bitmapRatio) * imageView.getHeight();
  drawTop = (imageView.getHeight() - drawHeight)/2;
}
else
{
  drawTop = 0;
  drawWidth = (bitmapRatio/imageViewRatio) * imageView.getWidth();
  drawLeft = (imageView.getWidth() - drawWidth)/2;
}
25
pheelicks

これは私が共有したかったメソッドです、それはgetImageMatrixを使用してimageView内のビットマップのオフセットを返します

public static int[] getBitmapOffset(ImageView img,  Boolean includeLayout) {
        int[] offset = new int[2];
        float[] values = new float[9];

        Matrix m = img.getImageMatrix();
        m.getValues(values);

        offset[0] = (int) values[5];
        offset[1] = (int) values[2];

        if (includeLayout) {
            ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) img.getLayoutParams();
            int paddingTop = (int) (img.getPaddingTop() );
            int paddingLeft = (int) (img.getPaddingLeft() );

            offset[0] += paddingTop + lp.topMargin;
            offset[1] += paddingLeft + lp.leftMargin;
        }
        return offset;
    }
26
Shlomi Schwartz

それがあなたが探しているものであれば、内部のドローアブルの(x、y)座標を取得できるはずです。これを試して:

ImageView img = (ImageView)findViewById(R.id.img);
Rect r = img.getDrawable().getBounds();

int drawLeft = r.left;
int drawTop = r.top;
int drawRight = r.right;
int drawBottom = r.bottom;

drawLeftはXの値です。

drawTopはY値です。

3
kcoppock

私自身、多くの問題を抱えていましたが、実際には非常に単純であることがわかりました:)

float points[] = {bitmap.getWidth()/2,bitmap.getHeight()/2}; matrix.mapPoints(points); matrix.postScale(scale, scale, points[0], points[1]);

1
Gilad