Accollativo
Accollativo

Reputation: 1559

Android magnify view and draw as bitmap

I've a camera and from this I take a photo and save a bitmap. Overlayed to this, there's a view pager, with different layouts. When I take a photo, I want to save the current overlayed layout too.

The problem is that photo and layout are both saved, the layout fix correctly in the bitmap area, but it's smaller in respect as was in the preview camera. I need to magnify the layout (to look as it was before to the photo) and to save it in my bitmap.

Before to take photo:

Before to take photo

After (it's ok that the button is still there, it's just a test):

after

My code:

                Bitmap cameraBitmap = BitmapFactory.decodeByteArray
                        (data, 0, data.length);

                int  wid = cameraBitmap.getWidth();
                int  hgt = cameraBitmap.getHeight();

                bitmap = Bitmap.createBitmap
                        (wid, hgt, Bitmap.Config.ARGB_8888);

                Canvas canvas = new Canvas(bitmap);
                canvas.drawBitmap(cameraBitmap, 0f, 0f, null);

                ViewPager pager = (ViewPager) main_activity.findViewById(R.id.pager);
                ScreenSlidePagerAdapter a = (ScreenSlidePagerAdapter) pager.getAdapter();
                ScreenSlidePageFragment currFrag = (ScreenSlidePageFragment) a.instantiateItem(pager, a.getFocusedPage());
                View currView = currFrag.getView();

                Rect rect = new Rect();
                rect.set(0, 0, wid, hgt);
                //Measure the view at the exact dimensions (otherwise the text won't center correctly)
                int widthSpec = View.MeasureSpec.makeMeasureSpec(rect.width(), View.MeasureSpec.EXACTLY);
                int heightSpec = View.MeasureSpec.makeMeasureSpec(rect.height(), View.MeasureSpec.EXACTLY);
                currView.measure(widthSpec, heightSpec);

                //Lay the view out at the rect width and height
                currView.layout(0, 0, rect.width(), rect.height());

                //Translate the Canvas into position and draw it
                canvas.save();
                canvas.translate(rect.left, rect.top);
                currView.draw(canvas);
                canvas.restore();

Upvotes: 0

Views: 180

Answers (2)

Accollativo
Accollativo

Reputation: 1559

I created a new bitmap with the view and I merged it with the previous bitmap, the result was good:

Bitmap cameraBitmap = BitmapFactory.decodeByteArray
        (data, 0, data.length);

int  wid = cameraBitmap.getWidth();
int  hgt = cameraBitmap.getHeight();

bitmap = Bitmap.createBitmap
        (wid, hgt, Bitmap.Config.ARGB_8888);

Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(cameraBitmap, 0f, 0f, null);

ViewPager pager = (ViewPager) main_activity.findViewById(R.id.pager);
ScreenSlidePagerAdapter a = (ScreenSlidePagerAdapter) pager.getAdapter();
ScreenSlidePageFragment currFrag = (ScreenSlidePageFragment) a.instantiateItem(pager, a.getFocusedPage());
View currView = currFrag.getView();

Bitmap viewBitmap = CustomUtil.loadBitmapFromView(currView);
viewBitmap = Bitmap.createScaledBitmap(viewBitmap, wid, wid, false);
canvas.drawBitmap(viewBitmap, 0f, (hgt-wid)/2 /* to center my square view in my rectangular original bitmap */, null);

An utility method:

public static Bitmap loadBitmapFromView(View view) {
    int width = view.getWidth();
    int height = view.getHeight();

    int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
    int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);

    //Cause the view to re-layout
    view.measure(measuredWidth, measuredHeight);
    view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());

    //Create a bitmap backed Canvas to draw the view into
    Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(b);

    //Now that the view is laid out and we have a canvas, ask the view to draw itself into the canvas
    view.draw(c);

    return b;   
}

Upvotes: 0

Game Programmer
Game Programmer

Reputation: 57

Why not create the bitmap with porportions. To do so, you need to create a Scalable Bitmap, and make the width like 1/4 of the screen and the height one fourth of the screen height.

To do so, first in the onCreate() method, also add in the following code to get the screenWidth and Height. -

metrics = getResources().getDisplayMetrics();
    display = getWindowManager().getDefaultDisplay();
    dpi = metrics.densityDpi;
    size = new Point();
    display.getSize(size);
    screenWidth = size.x;
    screenHeight = size.y;

To create a scalable bitmap use the following code, but remember to set the width and height values porportional such as the following --

public static int height = MainActivity.screenWidth* 4/10;
public static int width = MainActivity.screenWidth* 4/10;

bg = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
            if (width + heigt > 0) {
                bg = Bitmap.createScaledBitmap(bg,
                        (width), (heigt),
                        false);
            }

Also, to make sure the drawable images stay in quality, make sure to create seperate drawable folders, such as 'xxhdpi,and hdpi.'Refer to http://developer.android.com/guide/practices/screens_support.html. Hope that helps. Good luck.

Upvotes: 1

Related Questions