Android-如何在图像视图中获取图像边缘x/y位置?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (196)

如果我有一个填充屏幕的ImageView。

图像视图背景设置为绿色。

我在ImageView中放置一个位图,保持位图比例。

此布局中的肖像照片将显示左侧和右侧的绿色。

现在,当绿色结束和位图开始时,我如何得到边缘的左侧x/y位置。

这个努力项目的背景是,我想在图像上写文本,并将图像保存回一个新的文本图像。问题是:

由于我在SampleSize=4中缩放了图像,而且ImageView更缩小了它,保存这张新图片将提供一个小的大约250x350图像。

我想要的是使用x/y位置,并将书面文本传递到原始的inSampleSize=4图像或sdCard 1500x3000图像

我知道并阅读了关于这个的其他问题,我必须自己“做数学计算”,我只需要这个小小的答案。

这就是它的样子:

这是图像视图

    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; 
        }
    }
提问于
用户回答回答于

如果你知道这个比率,你只需要得到边框的宽度,它就会被放置在图像的一侧。

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

现在,如果位图比ImageViewRatio大,你知道这意味着如果位图的高度相等,位图比图像视图更宽。换句话说,在顶部和底部都会有空白。

相反,如果位映射比ImageViewRatio小,那么左右将有空白。从这里,你可以得到一个协调相当琐碎,因为它将是0!

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

要获得另一个协调,请考虑第二个情况,即你有左&右的空间。在这里,位图和图像视图的高度是相等的,因此宽度之间的比率等于两者之间的比率。你可以使用它来计算位图的宽度,因为你知道图像视图的宽度。同样,如果宽度相等,则可以计算出高度,但必须使用比率之间的反比,因为宽度与比率成反比:

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;
}
用户回答回答于

下面是我想要共享的方法,它将使用getImageMatrix返回图像视图中位图的偏移量

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

扫码关注云+社区