1
votes

I've coded my game for 320x480 and I figure that the easiest way to support multiple resolutions is to scale the end image. What are your thoughts on this? Would it be cpu efficient to do it this way?

I have all my images placed in the mdpi folder, I'll have it drawn unscaled on the screen onto a buffer, then scale it to fit the screen. all the user inputs will be scaled as well.

I have these 2 questions: -How do you draw a bitmap without android automatically scaling it -How do you scale a bitmap?

2

2 Answers

3
votes

I have stumbled upon the same problem a number of times in my projects and each time due to lack of time (and laziness) I would be satisfied with a less than optimum solution. But recently I found some time to crack down this particular issue. Here is my solution and I hope it helps you as well.

Bitmap scaleWithAspectRatio(Bitmap image)
        {
            int imaheVerticalAspectRatio,imageHorizontalAspectRatio;
            float bestFitScalingFactor=0;
            float percesionValue=(float) 0.2;

            //getAspect Ratio of Image
            int imageHeight=(int) (Math.ceil((double) image.getHeight()/100)*100);
            int imageWidth=(int) (Math.ceil((double) image.getWidth()/100)*100);
            int GCD=BigInteger.valueOf(imageHeight).gcd(BigInteger.valueOf(imageWidth)).intValue();
            imaheVerticalAspectRatio=imageHeight/GCD;
            imageHorizontalAspectRatio=imageWidth/GCD;
            Log.i("scaleDownLargeImageWIthAspectRatio","Image Dimensions(W:H): "+imageWidth+":"+imageHeight);
            Log.i("scaleDownLargeImageWIthAspectRatio","Image AspectRatio(W:H): "+imageHorizontalAspectRatio+":"+imaheVerticalAspectRatio);

            //getContainer Dimensions
            int displayWidth = getWindowManager().getDefaultDisplay().getWidth();
            int displayHeight = getWindowManager().getDefaultDisplay().getHeight();
           //I wanted to show the image to fit the entire device, as a best case. So my ccontainer dimensions were displayWidth & displayHeight. For your case, you will need to fetch container dimensions at run time or you can pass static values to these two parameters 

            int leftMargin = 0;
            int rightMargin = 0;
            int topMargin = 0;
            int bottomMargin = 0;
            int containerWidth = displayWidth - (leftMargin + rightMargin);
            int containerHeight = displayHeight - (topMargin + bottomMargin);
            Log.i("scaleDownLargeImageWIthAspectRatio","Container dimensions(W:H): "+containerWidth+":"+containerHeight);

            //iterate to get bestFitScaleFactor per constraints
            while((imageHorizontalAspectRatio*bestFitScalingFactor <= containerWidth) && 
                    (imaheVerticalAspectRatio*bestFitScalingFactor<= containerHeight))
            {
                bestFitScalingFactor+=percesionValue;
            }

            //return bestFit bitmap
            int bestFitHeight=(int) (imaheVerticalAspectRatio*bestFitScalingFactor);
            int bestFitWidth=(int) (imageHorizontalAspectRatio*bestFitScalingFactor);
            Log.i("scaleDownLargeImageWIthAspectRatio","bestFitScalingFactor: "+bestFitScalingFactor);
            Log.i("scaleDownLargeImageWIthAspectRatio","bestFitOutPutDimesions(W:H): "+bestFitWidth+":"+bestFitHeight);
            image=Bitmap.createScaledBitmap(image, bestFitWidth,bestFitHeight, true);

            //Position the bitmap centre of the container
            int leftPadding=(containerWidth-image.getWidth())/2;
            int topPadding=(containerHeight-image.getHeight())/2;
            Bitmap backDrop=Bitmap.createBitmap(containerWidth, containerHeight, Bitmap.Config.RGB_565);
            Canvas can = new Canvas(backDrop);
            can.drawBitmap(image, leftPadding, topPadding, null);

            return backDrop;
        }
0
votes

I am working on a game and I have targeted 1280x800 and I've made all of the images to match that resolution. The very first time I launch the game I scale all of the images down to match the current resolution and use the scaled images to actually draw the game. If you are using a SurfaceView then you shouldn't have problems with scaling images when you draw them. Just to be 100% sure I keep my images in the raw directory and load them from there.

To do the initial scaling of the bitmap you just need to use the BitmapFactory.Options when you decode the bitmap to tell it what density it's targeted for and what density it's actually going to be displayed on.