2013-02-27 4 views
11

Bitmapのサイズを固定サイズ(512x128など)に変更する方法については、次の問題の解決策を探しています。ビットマップコンテンツのアスペクト比は保持する必要があります。ビットマップを固定値にリサイズし、縦横比を変更しないでください

私はそれがこのようなものであるべきだと思う:アスペクト比を維持して512x128ピクセルに合わせて、空の512x128のビットマップ

  • 規模元のビットマップダウン

  • を作成

    • スケールされたビットマップを空のビットマップにコピーする(中央に置く)

    これを達成する最も簡単な方法は何ですか?

    なぜなら、画像のアスペクト比が異なると、GridViewはレイアウトを乱すからです。

    screenshot

  • 答えて

    25

    これを試して、比率を計算してから再スケーリングしてください。

    private Bitmap scaleBitmap(Bitmap bm) { 
        int width = bm.getWidth(); 
        int height = bm.getHeight(); 
    
        Log.v("Pictures", "Width and height are " + width + "--" + height); 
    
        if (width > height) { 
         // landscape 
         float ratio = (float) width/maxWidth; 
         width = maxWidth; 
         height = (int)(height/ratio); 
        } else if (height > width) { 
         // portrait 
         float ratio = (float) height/maxHeight; 
         height = maxHeight; 
         width = (int)(width/ratio); 
        } else { 
         // square 
         height = maxHeight; 
         width = maxWidth; 
        } 
    
        Log.v("Pictures", "after scaling Width and height are " + width + "--" + height); 
    
        bm = Bitmap.createScaledBitmap(bm, width, height, true); 
        return bm; 
    } 
    
    +2

    に加えて、単純な解決策が1つ追加されました。しかしint/intは0で割り算しようとすると例外を生成する可能性があるので、int ratioをfloat/double ratioに変更します。 –

    +0

    素晴らしいシンプルなソリューション! intの代わりに浮動小数点を使うことは必須です。それ以外の場合は、結果がほとんど間違っている可能性があります(たとえば、比率1.4のときに比率が1になるなど)。 – xip

    +0

    @Hikaruあなたは正しいですが、それをしたいと思っていましたが、決してそれに着いたことはありません。編集とリマインダーありがとう - ) –

    0

    https://developer.android.com/reference/android/graphics/Bitmap.html#createScaledBitmap(android.graphics.Bitmap, int, int, boolean)

    dstWidthdstHeight共にsrc.getWidth()*scalesrc.getHeight()*scaleから得られることを確認してください:ここでスクリーンショット(1:最後のものを除いて、すべての画像が4のアスペクト比を有する)でありますここで、scaleは、スケーリングされたビットマップが512x128に収まることを確認するために必要な値です。

    +0

    'createScaledBitmap'は私の問題を解決しません。それは私がすでに使っているものです。この例では、最後の画像がそのようにスケーリングされています。 –

    +0

    GridViewアイテムのImageViewで、これらの属性をandroid:layout_width = "512dp"およびandroid:layout_height = "128dpに設定して、縮小されたビットマップ(例では幅が512未満または128未満の場合) "android:scaleType =" center "またはandroid:scaleType =" centerInside " –

    +0

    私の説明によると、この例の最後の画像は既に縮小されているので、すでに最大です。 128px高い。それにもかかわらず、画像ビューはそれを他の画像よりも大きく表示する。また、私は512x128dpグリッドの画像ビューを望んでいません。 –

    2

    私は自分のプロジェクトで何度も同じ問題を抱えていましたが、時間が足りず(そして怠惰なため)、最適な解決策には満足できませんでした。しかし、最近私は、この特定の問題を解決するためにいくつかの時間を見つけました。ここに私の解決策があり、それが誰かを助けることを願っています。

    Bitmap scaleDownLargeImageWithAspectRatio(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; 
          } 
    
    18

    Coen Damenの回答は、Max HeightとMax Widthを必ずしも考慮していません。 答えは次のとおりです。

    private static Bitmap resize(Bitmap image, int maxWidth, int maxHeight) { 
        if (maxHeight > 0 && maxWidth > 0) { 
         int width = image.getWidth(); 
         int height = image.getHeight(); 
         float ratioBitmap = (float) width/(float) height; 
         float ratioMax = (float) maxWidth/(float) maxHeight; 
    
         int finalWidth = maxWidth; 
         int finalHeight = maxHeight; 
         if (ratioMax > 1) { 
          finalWidth = (int) ((float)maxHeight * ratioBitmap); 
         } else { 
          finalHeight = (int) ((float)maxWidth/ratioBitmap); 
         } 
         image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true); 
         return image; 
        } else { 
         return image; 
        } 
    } 
    
    +0

    }に私の答えを盗むのは良いです。もちろん、maxWidthとmaxHeightはメソッドparamsではなくクラス変数です。 –

    関連する問題