Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android - how to get the image edge x/y position inside imageview

If i have an ImageView that fills the screen.
The ImageView background is set to green color.
I place a bitmap in the ImageView, keeping bitmap proportions.

A portrait photo in this layout will show green on both left and right side
(Phone orientation= portrait).

Now, How do i get the left side x/y position of the edge when the green ends and bitmap begins.

The background for this endeavor project is that i want to write text on the image and save the image back to a new image with the text. The problem is..

Since I scale the image inSampleSize = 4; and the ImageView shrinking it even more, saving this new picture will give a small small approx 250x350 image.

What i want is to use the x/y positions and transfer the written text to the original inSampleSize = 4 image or to the sdcard 1500x3000 image

I know and read other questions about this that i have to "Do the math calculations" myself I just need this small answer.

I forgot i can take a screenshot to clarify.

this is what it look like: (I get a new pen on pressing the button "pen" each pen hold its own unique text and position on the screen

enter image description here

Here is the 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; 
        }
    }
like image 501
Erik Avatar asked May 16 '11 21:05

Erik


People also ask

Which attribute is used to set an image in ImageView * *?

src: src is an attribute used to set a source file or you can say image in your imageview to make your layout attractive.

Can ImageView be clickable?

Using clickable imagesYou can turn any View , such as an ImageView , into a button by adding the android:onClick attribute in the XML layout. The image for the ImageView must already be stored in the drawable folder of your project.

Can ImageView display video?

You can add ImageView and VideoView in RelativeLayout and set ImageView to invisible and VideoView to visible and vice-versa and you can play video on onClick.

What is adjustViewBounds?

android:adjustViewBounds—If set to true, the attribute adjusts the bounds of the ImageView control to maintain the aspect ratio of the image displayed through it.


2 Answers

Here is a method I wanted to share, it will return the offset of the bitmap inside an imageView using 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[Matrix.MTRANS_Y];
        offset[1] = (int) values[Matrix.MTRANS_X];

        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;
    }
like image 198
Shlomi Schwartz Avatar answered Sep 30 '22 03:09

Shlomi Schwartz


If you know the ratios you can just derive the width of the margin that will be placed to the side of the image.

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

Now, if the bitmapRatio is larger than the imageViewRatio, you know that this means that the bitmap is wider than the imageview if they have an equal height. In other words, you'll have blanks on the top & bottom.

Conversely, if bitmapRatio is smaller than imageViewRatio then you'll have blanks to the left and right. From this you can get one of the co-ordinates pretty trivially as it'll be 0!

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

To get the other co-ordinate, think about the second case where you have space left & right. Here the heights of the the bitmap and imageView are equal and thus the ratio between the widths is equal to ratio between the ratios. You can use this to figure out width of the bitmap as you know the width of the imageView. Similarly you can figure out the heights if the width are equal, except that you have to use the inverse of the ratio between the ratios as the width is inversely proportional the the ratio:

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

Once you have the width or height of the bitmap, getting the space to the side is simple, it is just half the difference between the bitmap and imageView width or height:

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;
}
like image 20
pheelicks Avatar answered Sep 30 '22 02:09

pheelicks