Размер растрового изображения превышает 32 бита

Я масштабирую растровое изображение с помощью панели поиска. Всякий раз, когда я увеличиваю ход панели поиска, масштабирование изображения не выполняется, выдавая ошибку «Размер растрового изображения превышает 32 бита». Если я масштабирую изображение со значением панели поиска по умолчанию. выдает ошибку «Исключение недопустимого аргумента: ширина и высота должны быть> 0».

Отчет журнала

07-26 05:20:23.189: E/AndroidRuntime(1145): FATAL EXCEPTION: main
07-26 05:20:23.189: E/AndroidRuntime(1145): java.lang.IllegalArgumentException: bitmap size exceeds 32bits
07-26 05:20:23.189: E/AndroidRuntime(1145):     at android.graphics.Bitmap.nativeCreate(Native Method)
07-26 05:20:23.189: E/AndroidRuntime(1145):     at android.graphics.Bitmap.createBitmap(Bitmap.java:697)
07-26 05:20:23.189: E/AndroidRuntime(1145):     at android.graphics.Bitmap.createBitmap(Bitmap.java:674)
07-26 05:20:23.189: E/AndroidRuntime(1145):     at android.graphics.Bitmap.createBitmap(Bitmap.java:607)
07-26 05:20:23.189: E/AndroidRuntime(1145):     at com.example.navigationexample.QRCodeGenerator.scaleImage(QRCodeGenerator.java:127)
07-26 05:20:23.189: E/AndroidRuntime(1145):     at com.example.navigationexample.MainActivity$3.onClick(MainActivity.java:356)
07-26 05:20:23.189: E/AndroidRuntime(1145):     at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:166)
07-26 05:20:23.189: E/AndroidRuntime(1145):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-26 05:20:23.189: E/AndroidRuntime(1145):     at android.os.Looper.loop(Looper.java:137)
07-26 05:20:23.189: E/AndroidRuntime(1145):     at android.app.ActivityThread.main(ActivityThread.java:5103)
07-26 05:20:23.189: E/AndroidRuntime(1145):     at java.lang.reflect.Method.invokeNative(Native Method)
07-26 05:20:23.189: E/AndroidRuntime(1145):     at java.lang.reflect.Method.invoke(Method.java:525)
07-26 05:20:23.189: E/AndroidRuntime(1145):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
07-26 05:20:23.189: E/AndroidRuntime(1145):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
07-26 05:20:23.189: E/AndroidRuntime(1145):     at dalvik.system.NativeStart.main(Native Method)
07-26 05:20:25.857: I/Process(1145): Sending signal. PID: 1145 SIG: 9

Фрагмент кода

public void showSaveDialog() {

    LayoutInflater inflater = getLayoutInflater();
    dialog = null;

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Save QR Image");

    View v = inflater.inflate(R.layout.save_dialog, null);
    builder.setView(v);

    final EditText et = (EditText) v.findViewById(R.id.qrName);
    et.setMaxLines(1);

    final TextView widthText = (TextView) v.findViewById(R.id.widthSize);
    final TextView heightText = (TextView) v.findViewById(R.id.heightSize);

    SeekBar seekBar = (SeekBar) v.findViewById(R.id.seekBar1);

    seekBar.setMax(16);

    // To set minimum value of seekbar
    seekMin = seekBar.getProgress();
    if (seekMin < 128) {
        seekBar.setProgress(1);
        widthText.setText("128");
        heightText.setText("128");
    }

    seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

        @Override
        public void onStopTrackingTouch(SeekBar arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onStartTrackingTouch(SeekBar arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progresValue,
                boolean fromUser) {
            // TODO Auto-generated method stub
            val = progresValue * 128;
            String size = String.valueOf(val);
            widthText.setText(size);
            heightText.setText(size);
        }
    });

    builder.setPositiveButton("Save", new OnClickListener() {

        @Override
        public void onClick(DialogInterface arg0, int arg1) {
            // TODO Auto-generated method stub
            qrName = et.getText().toString();

            if (qrName.isEmpty()) {
                Toast.makeText(getApplicationContext(),
                        "Please enter name", Toast.LENGTH_SHORT).show();
            } else {

                Bitmap sImg = classB.scaleImage(image, val, density);
                saveImage(sImg);
            }
        }
    });
    dialog = builder.create();
    dialog.show();
}

Функция масштабирования изображения в классе B

public Bitmap scaleImage(Bitmap bitmap, int bound, int density) {

    int w = bitmap.getWidth();
    int h = bitmap.getHeight();

    // Get current dimensions AND the desired bounding box
    int bounding = dpToPx(bound, density);
    Log.i("Test", "original width = " + Integer.toString(w));
    Log.i("Test", "original height = " + Integer.toString(h));
    Log.i("Test", "bounding = " + Integer.toString(bounding));

    // Determine how much to scale: the dimension requiring less scaling is
    // closer to the its side. This way the image always stays inside your
    // bounding box AND either x/y axis touches it.
    float xScale = ((float) bounding) / w;
    float yScale = ((float) bounding) / h;
    float scale = (xScale <= yScale) ? xScale : yScale;
    Log.i("Test", "xScale = " + Float.toString(xScale));
    Log.i("Test", "yScale = " + Float.toString(yScale));
    Log.i("Test", "scale = " + Float.toString(scale));

    // Create a matrix for the scaling and add the scaling data
    Matrix matrix = new Matrix();
    matrix.postScale(scale, scale);

    // Create a new bitmap and convert it to a format understood by the
    // ImageView
    Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix,
            true);
    sWidth = scaledBitmap.getWidth(); // re-use
    sHeight = scaledBitmap.getHeight(); // re-use
    @SuppressWarnings("deprecation")
    BitmapDrawable result = new BitmapDrawable(scaledBitmap);
    Log.i("Test", "scaled width = " + Integer.toString(sWidth));
    Log.i("Test", "scaled height = " + Integer.toString(sHeight));

    return scaledBitmap;
}

Функция для получения граничного значения в функции scaleImage()

private int dpToPx(int dp, int density) {
    int result = Math.round((float) dp * density);
    return result;
}

person user3864752    schedule 26.07.2014    source источник
comment
Похоже, вы пытаетесь масштабировать либо до слишком большого размера, либо до 0. Когда вы создаете растровое изображение, что такое w, h и масштаб?   -  person Gabe Sechan    schedule 26.07.2014
comment
По умолчанию прогресс панели поиска равен 1. При этом прогрессе я получаю, что ширина и высота должны быть > 0, а значения журнала: исходная ширина = 540, исходная высота = 540, граница = 0, xScale = 0,0, yScale = 0,0, масштаб = 0,0   -  person user3864752    schedule 26.07.2014
comment
Ну, масштаб равен 0, это вызовет проблему. Масштабирование чего-либо до 0 даст вам 0 высоты и ширины.   -  person Gabe Sechan    schedule 26.07.2014
comment
Итак, есть ли решение?   -  person user3864752    schedule 26.07.2014
comment
Да, похоже, что ограничение равно 0, несмотря ни на что. Исправьте это. Я предполагаю, что вы не указали значение по умолчанию для val в своем классе активности, поэтому оно инициализируется равным 0.   -  person Gabe Sechan    schedule 26.07.2014
comment
я передаю это val = progresValue * 128;   -  person user3864752    schedule 26.07.2014
comment
Но только если когда-либо вызывается onProgressChanged. Если это не так, val никогда не устанавливается.   -  person Gabe Sechan    schedule 26.07.2014
comment
Да, ты прав. Я проверил это. При прогрессе панели поиска по умолчанию значение val var равно 0.   -  person user3864752    schedule 26.07.2014
comment
Я передаю 128 для переменной val, когда ход поиска не меняется. Теперь выдает ошибку, что размер растрового изображения превышает 32 бита.   -  person user3864752    schedule 26.07.2014


Ответы (1)


Какое значение вы передаете в аргумент density вашего метода dpToPx(int,int)?

Ваш метод объявляет плотность как int, что наводит меня на мысль, что вы, возможно, передаете DisplayMetrics.densityDpi, трехзначное число int. Что вы имели в виду, чтобы использовать DisplayMetrics.density, однозначный номер float. Это вытолкнет размер вашего изображения за пределы 32 бит:

threshold 32 bits signed int = 2^31 -1         =  2147483647

progressValue = 16
bitmap edge   = 16 * 128     = 2048
bitmap size   = 2048^2       = 4194304
at 32 bpp     = 4194304 * 32 = 134217728

multiplied by densityDpi     = 134217728 * 460 = 61740154880  // kaboom
multiplied by density        = 134217728 * 3   =   402653184  // ok
person Barend    schedule 26.07.2014
comment
При этих значениях вылетает, выдавая ошибку Out of Memory progressValue = 16, bitmap edge = 16*128 = 2048 - person user3864752; 26.07.2014