10

ビットマップファイルを縮小するために「developer.android.com」を探していますが、理解できないことが1つ見つかりました。少し助けてくれてありがとう。

これがdeveloper.android.comからの抜粋です

public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
  // Raw height and width of image
  final int height = options.outHeight;
  final int width = options.outWidth;
  int inSampleSize = 1;

  if (height > reqHeight || width > reqWidth) {
    if (width > height) {
      inSampleSize = Math.round((float)height / (float)reqHeight);
    } else {
      inSampleSize = Math.round((float)width / (float)reqWidth);
    }
  }
  return inSampleSize;
}

ifステートメントで、「if(width> height)」の場合、なぜ「(float)height /(float)reqHeight」を計算するのですか?

たとえば、width = 600、height = 800、reqWidth = 100、reqHeight=100です。

この状況では、inSampleSizeは6になり、計算されるディメンションはwidth = 100、height=133になります。高さはまだreqHeightを超えています。

それで、誰かがこれについて私に説明できますか?複雑な説明で申し訳ありませんが、誰かが私にアイデアをくれたらいいのにと思います。:)

4

5 に答える 5

4

私が言えるのは、彼らのロジックが間違っているように見えるということだけです:(とにかく、このメソッドはかなり単純なので、正しい条件で再実装することはそれほど問題にはなりません!つまり、decodeSampledBitmapFromResource を見ると、それはビットマップを縮小して目的の境界に収まるようにしたいだけなので、これはエラーでなければなりません。

編集::それは、場合によってはうまくいかないので、さらに悪いように見えます。幅 = 200 と高さ = 600 があるとします。最大境界を幅 = 100 と高さ = 500 に設定します。高さ > 幅がありますが、両方を戻り結果に合わせたい場合は、inSampleSize を 200/100 にする必要があります。 600/500ではありません。したがって、基本的にメソッドを再実装する場合は、次のようにします。

public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;

    int stretch_width = Math.round((float)width / (float)reqWidth);
    int stretch_height = Math.round((float)height / (float)reqHeight);

    if (stretch_width <= stretch_height) 
        return stretch_height;
    else 
        return stretch_width;
}

しかし、それは彼らのコードの問題が多すぎて、私がその要点を正しく理解しているとは思えません!

于 2012-12-04T08:34:11.070 に答える
3

さて、スケーリングに関する多くの問題を抱えた後、私は自分の答えを得たと思います:

http://developer.android.com/training/displaying-bitmaps/load-bitmap.htmlの「大きなビットマップを効率的にロードする」を使用して、結果の一部を投稿したいと思います(以下の元のコード):

// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);

私は現在、横向きモードで解像度 1280 x 752 の Galaxy-Tab 7.7 に取り組んでいます。次の仕様の画像を想像してください。

1920 x 1200 .. どうなりますか?

heighRatio = 1920/1280 = 1.5および widthRatio = 1200/752 = 1.59

両方の数値が2に丸められるため、すべてが正しく理解されていれば、画像は 2 倍に縮小されます。これにより、画像は 1920/2 = 960 * 600になり、これは私の必要な解像度1280 * 752よりも小さくなります。

私はこれを床ごとに置き換えることで解決しました:

// Calculate ratios of height and width to requested height and width
final int heightRatio = (int)Math.floor((float) height / (float) reqHeight);
final int widthRatio = (int)Math.floor((float) width / (float) reqWidth);

これにより、一部の画像が縮小されすぎるのを実際に防ぐことができます。現在、パラメーターinSampleSizeを調査して、「分数」を使用できるかどうかを確認しています。現在、1280x752 (*2) = 2560*1504 のサイズまでのすべての画像はスケーリングされません。私がこれを書いている imageView は画像の詳細なビューなので、今はあまり問題にならないはずです。

コード内の修正版を以下と組み合わせて使用​​します。

returnview.setAdjustViewBounds(true);

これにより、画像が画面よりも大きくなり、バウンディング ボックスが台無しになるのを防ぐことができます。実際の画像にカラーバックラウンドを設定すると確認できます。さらに、修正されたコードを使用して、ユーザーが画像の外側をクリックして画像を閉じるかどうかを検出する onClick Handler を実装できます。

于 2013-03-14T23:40:01.520 に答える
0

私は彼らの論理を見つけます

if (height > reqHeight || width > reqWidth) {
    if (width > height) {
        inSampleSize = Math.round((float)height / (float)reqHeight);
    } else {
        inSampleSize = Math.round((float)width / (float)reqWidth);
    }
}

も紛らわしい。私はもっ​​と簡単なアプローチをとります。私のロジックは、画像が水平画像の場合は幅に合わせて拡大縮小し、必要な高さを無視し、垂直画像の場合は画像を高さに合わせて拡大縮小し、必要な幅を無視します。

if (height > reqHeight || width > reqWidth) {
        if (width > height) {
            inSampleSize = Math.round((float) width / (float) reqWidth);
        } else {
            inSampleSize = Math.round((float) height / (float) reqHeight);
        }
    }
于 2013-04-02T16:17:24.950 に答える