0
votes

I am having a trouble with my custom Image view:

The view is set to type matrix. I basically load a map (indoor floor plan) to this custom view and want to drag, zoom and rotate by multitouch. I succeeded in all that but the problem happened when I rotate the view like this:

m_Matrix.PostRotate(mAngle, m_Width/2, m_Height/2);
                        ImageMatrix = m_Matrix;

, then scale it to 1:

m_Matrix.PostScale(1/Scale,1/Scale,m_Width/2,m_Height/2);
ImageMatrix = m_Matrix;

; where Scale is the old scale, m_width and m_height are the original width and height. I find that the image gets bigger from 0-90 and 180-270 and return to normal from 90-180 and 270-360. I researched and knew that the image gets bigger when it is rotated. Fine! now I want to know the new dimensions after each rotation, such that I will calculate the new scale and apply it, so that the image will look stable to the user after rotation.

The problem now is that when the image is rotated, the view.getwidth and getheight does return the original width and height. I also tried view.measure() and then check the measured width and height but same results. The only success was by using:

Bitmap originalBitmap = ((BitmapDrawable)Drawable).Bitmap;
Bitmap newBitmap = Bitmap.CreateBitmap(originalBitmap, 0, 0,
                            m_Width, m_Height, m_Matrix, true); 

which now give me the new dimensions, but the problem with this is it takes a lot of memory such that I can't create a new bitmap after every rotation.

Now could you please advise on this? The summary again: postscale(1) after a rotation does show a bigger image but does not change the size of the view when measured. I want to get the new dimensions.

Many thanks in advance. Amir

1

1 Answers

0
votes

Great after trying many approaches to achieve my requirement which was bounding my custom view after matrix manipulations (drag, zoom and rotation), I want to share this with you so it can help someone.

public void Cutting ()
        {

            //this function ensures that a picture is bounded and also center the picture by padding it 

            m_Matrix= cutMatrix (m_Matrix);    
            ImageMatrix = m_Matrix;

        }
        public Matrix cutMatrix(Matrix matrix)
        {
            RectF rect;
            rect = new RectF (this.Left, this.Top, this.Right, this.Bottom);
            matrix.MapRect (rect);

            if (rect.Right < m_Width)
            {
                matrix.PostTranslate(-rect.Right + m_Width, 0);
            }
            rect = new RectF (this.Left, this.Top, this.Right, this.Bottom);
            matrix.MapRect (rect);

            if (rect.Left > 0)
            {
                matrix.PostTranslate(-rect.Left, 0);
            }

            rect = new RectF (this.Left, this.Top, this.Right, this.Bottom);
            matrix.MapRect (rect);

            if (rect.Bottom < m_Height)
            {
                matrix.PostTranslate(0, -rect.Bottom + m_Height);
            }

            rect = new RectF (this.Left, this.Top, this.Right, this.Bottom);
            matrix.MapRect (rect);

            if (rect.Top > 0)
            {
                matrix.PostTranslate(0, -rect.Top);
            }

            rect = new RectF (this.Left, this.Top, this.Right, this.Bottom);
            matrix.MapRect (rect);

            if (rect.Width() < myLayout.Width)
            {
                matrix.PostTranslate((myLayout.Width - rect.Width()) / 2, 0);
            }
            rect = new RectF (this.Left, this.Top, this.Right, this.Bottom);
            matrix.MapRect (rect);

            if (rect.Height() < myLayout.Height)
            {
                matrix.PostTranslate(0, (myLayout.Height - rect.Height()) / 2);
            }

            return matrix;
        }

This piece of code bounds you custom view after matrix manipulations, such that your view is never out of screen. Do the manipulation on matrix m_Matrix, then pass it to the function cutting and then set your custom imageview's matrix ImageMatrix with the new matrix. This code is written in xamarin but very straight forward to map it in java. Hope it helps some one!