157

ビットマップをImageViewにロードしていますが、このエラーが表示されます。この制限は、OpenGLハードウェアテクスチャのサイズ制限(2048x2048)に関連していると思います。ロードする必要のある画像は、高さ約4,000ピクセルのピンチズーム画像です。

マニフェストでハードウェアアクセラレーションをオフにしてみましたが、喜びはありません。

    <application
        android:hardwareAccelerated="false"
        ....
        >

2048ピクセルを超える画像をImageViewにロードすることは可能ですか?

4

17 に答える 17

409

これは質問に対する直接の答えではありませんが(画像の読み込み> 2048)、エラーが発生した場合の解決策として考えられます。

私の場合、画像は両方のサイズで2048より小さく(正確には1280x727)、この問題はGalaxyNexusで特に発生しました。画像はdrawableフォルダ内にあり、修飾されたフォルダはありませんでした。Androidは、密度修飾子のないドローアブルがmdpiであると想定し、他の密度の場合はスケールアップまたはスケールダウンします。この場合、xhdpiの場合は2倍にスケールアップします。スケーリングを防ぐために原因画像をに移動するとdrawable-nodpi、問題が解決しました。

于 2013-02-14T14:57:56.970 に答える
108

私はこのように画像を縮小しました:

ImageView iv  = (ImageView)waypointListView.findViewById(R.id.waypoint_picker_photo);
Bitmap d = new BitmapDrawable(ctx.getResources() , w.photo.getAbsolutePath()).getBitmap();
int nh = (int) ( d.getHeight() * (512.0 / d.getWidth()) );
Bitmap scaled = Bitmap.createScaledBitmap(d, 512, nh, true);
iv.setImageBitmap(scaled);
于 2013-03-27T17:57:55.530 に答える
51

すべてのレンダリングはOpenGLに基づいているため、この制限を超えることはできません(GL_MAX_TEXTURE_SIZEデバイスによって異なりますが、最小値は2048x2048であるため、2048x2048未満の画像が収まります)。

このような大きな画像で、ズームインしたい場合やモバイルで、たとえばグーグルマップで見られるものと同様のシステムをセットアップする必要があります。画像がいくつかの部分に分割され、いくつかの定義があります。

または、画像を表示する前に縮小することもできます(この質問に関するuser1352407の回答を参照してください)。

また、画像をどのフォルダに配置するかに注意してください。Androidは画像を自動的に拡大できます。この質問に関する以下のPilot_51の回答をご覧ください。

于 2012-04-22T19:02:27.397 に答える
34

このすべてのダウンサンプリングコードを手動で記述/デバッグしようと何時間も費やす代わりに、なぜ使用しないのPicassoですか?bitmapsそれはすべてのタイプおよび/またはサイズ を扱うために作られました。

この1行のコードを使用して、「ビットマップが大きすぎます...」という問題を削除しました。

Picasso.load(resourceId).fit().centerCrop().into(imageView);
于 2015-03-21T04:23:09.803 に答える
21

AndroidManifest.xml( )に次の2つの属性を追加すると、うまくいきました。

android:largeHeap="true"
android:hardwareAccelerated="false"
于 2016-11-27T11:55:14.273 に答える
16

画像ファイルをdrawable-nodpiフォルダからdrawableフォルダに変更することは私のために働いた。

于 2015-12-29T12:59:56.153 に答える
9

Picassoを使用しましたが、同じ問題が発生しました。画像は、少なくともサイズ、幅、または高さが大きすぎました。ついに私はここで解決策を見つけました。表示サイズに応じて大きな画像を縮小し、アスペクト比を維持することもできます。

    public Point getDisplaySize(Display display) {
    Point size = new Point();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
        display.getSize(size);
    } else {
        int width = display.getWidth();
        int height = display.getHeight();
        size = new Point(width, height);
    }

    return size;
}

Picassoによる画像の読み込みには、次の方法を使用します。

    final Point displySize = getDisplaySize(getWindowManager().getDefaultDisplay());
        final int size = (int) Math.ceil(Math.sqrt(displySize.x * displySize.y));
        Picasso.with(this)
                .load(urlSource)
                .resize(size, size)
                .centerInside()
                .into(imageViewd);

また、パフォーマンスを向上させるために、画像全体ではなく、表示画面の幅と高さに応じて画像をダウンロードできます。

    public String reviseImageUrl(final Integer displayWidth,     final Integer displayHeight,
        final String originalImageUrl) {
    final String revisedImageUrl;

    if (displayWidth == null && displayHeight == null) {
        revisedImageUrl = originalImageUrl;
    } else {
        final Uri.Builder uriBuilder = Uri.parse(originalImageUrl).buildUpon();

        if (displayWidth != null && displayWidth > 0) {
            uriBuilder.appendQueryParameter(QUERY_KEY_DISPLAY_WIDTH, String.valueOf(displayWidth));
        }

        if (displayHeight != null && displayHeight > 0) {
            uriBuilder.appendQueryParameter(QUERY_KEY_DISPLAY_HEIGHT, String.valueOf(displayHeight));
        }

        revisedImageUrl = uriBuilder.toString();
    }

    return revisedImageUrl;
}

    final String newImageUlr = reviseImageUrl(displySize.x, displySize.y, urlSource);

その後:

    Picasso.with(this)
                .load(newImageUlr)
                .resize(size, size)
                .centerInside()
                .into(imageViewd);

編集:getDisplaySize()

display.getWidth()/getHeight()非推奨です。Display使用する代わりにDisplayMetrics

public Point getDisplaySize(DisplayMetrics displayMetrics) {
        int width = displayMetrics.widthPixels;
        int height = displayMetrics.heightPixels;
        return new Point(width, height);
}
于 2015-07-30T20:53:32.133 に答える
6

BitmapRegionDecoderトリックを行います。

オーバーライドonDraw(Canvas canvas)して、新しいスレッドを開始し、ユーザーに表示される領域をデコードできます。

于 2013-04-18T21:45:47.417 に答える
5

Larchoが指摘しているように、APIレベル10BitmapRegionDecoderから、画像から特定の領域を読み込むために使用できます。これにより、必要な領域だけをメモリに割り当てることで、大きな画像を高解像度で表示できます。私は最近、タッチジェスチャ処理で大きな画像を視覚化するライブラリを開発しました。ソースコードとサンプルはこちらから入手できます

于 2014-01-05T15:40:36.763 に答える
4

ビューレベル

次のコードを使用して、実行時に個々のビューのハードウェアアクセラレーションを無効にできます。

myView.setLayerType(View.LAYER_TYPE_SOFTWARE、null);

于 2015-02-05T10:51:43.600 に答える
3

私は同じ問題に遭遇しました、これが私の解決策です。画像の幅をAndroidの画面幅と同じに設定してから、高さを調整します

Bitmap myBitmap = BitmapFactory.decodeFile(image.getAbsolutePath());
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Log.e("Screen width ", " "+width);
Log.e("Screen height ", " "+height);
Log.e("img width ", " "+myBitmap.getWidth());
Log.e("img height ", " "+myBitmap.getHeight());
float scaleHt =(float) width/myBitmap.getWidth();
Log.e("Scaled percent ", " "+scaleHt);
Bitmap scaled = Bitmap.createScaledBitmap(myBitmap, width, (int)(myBitmap.getWidth()*scaleHt), true);
myImage.setImageBitmap(scaled);

これは、あらゆるサイズのAndroid画面に適しています。それがあなたのために働くかどうか私に知らせてください。

于 2015-05-17T15:28:37.563 に答える
2

画像を縮小します:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;

// Set height and width in options, does not return an image and no resource taken
BitmapFactory.decodeStream(imagefile, null, options);

int pow = 0;
while (options.outHeight >> pow > reqHeight || options.outWidth >> pow > reqWidth)
    pow += 1;
options.inSampleSize = 1 << pow; 
options.inJustDecodeBounds = false;
image = BitmapFactory.decodeStream(imagefile, null, options);

画像はreqHeightとreqWidthのサイズで縮小されます。私が理解しているように、inSampleSizeは2の累乗の値しか取りません。

于 2014-02-27T12:39:24.610 に答える
2

imageviewに直接ロードする代わりに、Glideライブラリを使用します

グライド:https ://github.com/bumptech/glide

Glide.with(this).load(Uri.parse(filelocation))).into(img_selectPassportPic);
于 2018-05-17T06:56:06.703 に答える
1

私は上記のすべての解決策を次々とかなりの時間試しましたが、どれもうまくいかなかったようです!最後に、Androidのカメラで画像をキャプチャして表示することに関する公式の例を探すことにしました。公式の例(ここ)は、ついに私にうまくいった唯一の方法を与えました。以下に、そのサンプルアプリで見つけたソリューションを示します。

public void setThumbnailImageAndSave(final ImageView imgView, File imgFile) {

            /* There isn't enough memory to open up more than a couple camera photos */
    /* So pre-scale the target bitmap into which the file is decoded */

    /* Get the size of the ImageView */
    int targetW = imgView.getWidth();
    int targetH = imgView.getHeight();

    /* Get the size of the image */
    BitmapFactory.Options bmOptions = new BitmapFactory.Options();
    bmOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(imgFile.getAbsolutePath(), bmOptions);
    int photoW = bmOptions.outWidth;
    int photoH = bmOptions.outHeight;

    /* Figure out which way needs to be reduced less */
    int scaleFactor = 1;
    if ((targetW > 0) || (targetH > 0)) {
        scaleFactor = Math.min(photoW/targetW, photoH/targetH);
    }

    /* Set bitmap options to scale the image decode target */
    bmOptions.inJustDecodeBounds = false;
    bmOptions.inSampleSize = scaleFactor;
    bmOptions.inPurgeable = true;

    /* Decode the JPEG file into a Bitmap */
    Bitmap bitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath(), bmOptions);

    /* Associate the Bitmap to the ImageView */
    imgView.setImageBitmap(bitmap);
    imgView.setVisibility(View.VISIBLE);
}
于 2015-11-05T11:19:40.867 に答える
0

小さいサイズの画像を入れたい人への注意:

Pilot_51のソリューション(画像をdrawable-nodpiフォルダーに移動する)は機能しますが、別の問題があります。画像が画面に合わせて非常に大きい(2000 x 3800など)解像度にサイズ変更されない限り、画面上で画像が小さすぎるため、アプリが重くなります

解決策:画像ファイルを入れてくださいdrawable-hdpi-それは私にとって魅力のように機能しました。

于 2016-06-30T18:07:12.753 に答える
0

正しいドローアブルサブフォルダを使用することで解決しました。私の解決策は、フル解像度の画像(1920x1200)を、ドローアブルフォルダーではなくドローアブルxhdpiフォルダーに配置することでした。

また、縮小した画像(1280x800)をdrawable-hdpiフォルダーに入れました。

これらの2つの解像度は、私がプログラミングしている2013年と2012年のNexus7タブレットと一致します。また、他のいくつかのタブレットでソリューションをテストしました。

于 2017-04-21T21:24:51.717 に答える
0
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    super.onActivityResult(requestCode, resultCode, data);
    ///*
    if (requestCode == PICK_FROM_FILE && resultCode == RESULT_OK && null != data){



        uri = data.getData();

        String[] prjection ={MediaStore.Images.Media.DATA};

        Cursor cursor = getContentResolver().query(uri,prjection,null,null,null);

        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(prjection[0]);

        ImagePath = cursor.getString(columnIndex);

        cursor.close();

        FixBitmap = BitmapFactory.decodeFile(ImagePath);

        ShowSelectedImage = (ImageView)findViewById(R.id.imageView);

      //  FixBitmap = new BitmapDrawable(ImagePath);
        int nh = (int) ( FixBitmap.getHeight() * (512.0 / FixBitmap.getWidth()) );
        FixBitmap = Bitmap.createScaledBitmap(FixBitmap, 512, nh, true);

       // ShowSelectedImage.setImageBitmap(BitmapFactory.decodeFile(ImagePath));

        ShowSelectedImage.setImageBitmap(FixBitmap);

    }
}

このコードは機能しています

于 2017-07-16T07:19:33.087 に答える