Масштабирование изображения для Android для поддержки нескольких разрешений

Я закодировал свою игру для 320x480, и я считаю, что самый простой способ поддержки нескольких разрешений - масштабировать конечное изображение. Что вы думаете об этом? Было ли это эффективным cpu таким образом?

У меня есть все мои изображения, помещенные в папку mdpi, я нарисую его на экране безмасштабированным на буфере, а затем масштабирую его, чтобы он соответствовал экрану. все пользовательские входы также будут масштабироваться.

У меня есть два вопроса: -Как вы рисуете растровое изображение без андроида, автоматически масштабируя его -Как вы масштабируете растровое изображение?

Ответ 1

Я неоднократно сталкивался с той же проблемой несколько раз в своих проектах, и каждый раз из-за нехватки времени (и лени) я был бы удовлетворен менее оптимальным решением. Но недавно я нашел некоторое время, чтобы решить эту проблему. Вот мое решение, и я надеюсь, что это поможет вам.

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

Ответ 2

Я работаю над игрой, и я нацелился на 1280x800, и я сделал все изображения в соответствии с этим разрешением. В первый раз, когда я запускаю игру, я масштабирую все изображения до соответствия текущему разрешению и использую масштабированные изображения, чтобы на самом деле рисовать игру. Если вы используете SurfaceView, у вас не должно быть проблем с масштабированием изображений при их рисовании. Просто чтобы быть уверенным на 100%, я сохраняю свои изображения в исходном каталоге и загружаю их оттуда.

Для первоначального масштабирования растрового изображения вам просто нужно использовать BitmapFactory.Options, когда вы декодируете растровое изображение, чтобы рассказать ему, какую плотность он предназначенный для и на какой плотности он будет отображаться.