位图大小超过32位 [英] Bitmap size exceeds 32bits

查看:603
本文介绍了位图大小超过32位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用搜索栏缩放位图。每当我增加搜索栏的进步,图像缩放给予错误位图大小超过32位失败。如果我与扩展默认搜索栏值图像。它给出了一个错误。非法参数异常:宽度和高度必须> 0

日志报告

 五月7日至26日:20:23.189:E / AndroidRuntime(1145):致命异常:主要
5月7日至26日:20:23.189:E / AndroidRuntime(1145):java.lang.IllegalArgumentException异常:位图大小超过32位
5月7日至26日:20:23.189:E / AndroidRuntime(1145):在android.graphics.Bitmap.nativeCreate(本机方法)
5月7日至26日:20:23.189:E / AndroidRuntime(1145):在android.graphics.Bitmap.createBitmap(Bitmap.java:697)
5月7日至26日:20:23.189:E / AndroidRuntime(1145):在android.graphics.Bitmap.createBitmap(Bitmap.java:674)
5月7日至26日:20:23.189:E / AndroidRuntime(1145):在android.graphics.Bitmap.createBitmap(Bitmap.java:607)
5月7日至26日:20:23.189:E / AndroidRuntime(1145):在com.example.navigationexample.QR codeGenerator.scaleImage(QR codeGenerator.java:127)
5月7日至26日:20:23.189:E / AndroidRuntime(1145):在com.example.navigationexample.MainActivity $ 3.onClick(MainActivity.java:356)
5月7日至26日:20:23.189:E / AndroidRuntime(1145):在com.android.internal.app.AlertController $ ButtonHandler.handleMessage(AlertController.java:166)
5月7日至26日:20:23.189:E / AndroidRuntime(1145):在android.os.Handler.dispatchMessage(Handler.java:99)
5月7日至26日:20:23.189:E / AndroidRuntime(1145):在android.os.Looper.loop(Looper.java:137)
5月7日至26日:20:23.189:E / AndroidRuntime(1145):在android.app.ActivityThread.main(ActivityThread.java:5103)
5月7日至26日:20:23.189:E / AndroidRuntime(1145):在java.lang.reflect.Method.invokeNative(本机方法)
5月7日至26日:20:23.189:E / AndroidRuntime(1145):在java.lang.reflect.Method.invoke(Method.java:525)
5月7日至26日:20:23.189:E / AndroidRuntime(1145):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:737)
5月7日至26日:20:23.189:E / AndroidRuntime(1145):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
5月7日至26日:20:23.189:E / AndroidRuntime(1145):在dalvik.system.NativeStart.main(本机方法)
5月7日至26日:20:25.857:I /流程(1145年):发送信号。 PID:1145 SIG:9

code段

 公共无效showSaveDialog(){    LayoutInflater吹气= getLayoutInflater();
    对话框= NULL;    AlertDialog.Builder建设者=新AlertDialog.Builder(本);
    builder.setTitle(保存图片QR);    视图V = inflater.inflate(R.layout.save_dialog,NULL);
    builder.setView(五);    最终的EditText等=(EditText上)v.findViewById(R.id.qrName);
    et.setMaxLines(1);    最终的TextView widthText =(TextView中)v.findViewById(R.id.widthSize);
    最终的TextView heightText =(TextView中)v.findViewById(R.id.heightSize);    搜索栏搜索栏=(搜索栏)v.findViewById(R.id.seekBar1);    seekBar.setMax(16);    //设置搜索栏的最小值
    seekMin = seekBar.getProgress();
    如果(seekMin< 128){
        seekBar.setProgress(1);
        widthText.setText(128);
        heightText.setText(128);
    }    seekBar.setOnSeekBarChangeListener(新OnSeekBarChangeListener(){        @覆盖
        公共无效onStopTrackingTouch(搜索栏为arg0){
            // TODO自动生成方法存根        }        @覆盖
        公共无效onStartTrackingTouch(搜索栏为arg0){
            // TODO自动生成方法存根        }        @覆盖
        公共无效onProgressChanged(搜索栏搜索栏,INT progresValue,
                布尔FROMUSER){
            // TODO自动生成方法存根
            VAL = progresValue * 128;
            字符串的大小=将String.valueOf(VAL);
            widthText.setText(大小);
            heightText.setText(大小);
        }
    });    builder.setPositiveButton(保存,新OnClickListener(){        @覆盖
        公共无效的onClick(DialogInterface为arg0,ARG1 INT){
            // TODO自动生成方法存根
            。qrName = et.getText()的toString();            如果(qrName.isEmpty()){
                Toast.makeText(getApplicationContext(),
                        请输入名称,Toast.LENGTH_SHORT).show();
            }其他{                位图SIMG = classB.scaleImage(图像,缬氨酸,密度);
                saveImage(SIMG);
            }
        }
    });
    对话框= builder.create();
    dialog.show();
}

功能规模图像中的B类

 公共位图scaleImage(位图位图,诠释结合,诠释密度){    INT W = bitmap.getWidth();
    INT H = bitmap.getHeight();    //获取当前尺寸和所需的边框
    INT边界= dpToPx(结合,密度);
    Log.i(测试,原始宽度=+ Integer.toString(W));
    Log.i(测试,原来的高度=+ Integer.toString(H));
    Log.i(测试,边界=+ Integer.toString(边界));    //确定多少扩展:尺寸要求较少的比例为
    //靠近其侧面。通过这种方式,图像始终保持你的内
    //边框,要么X / Y轴接触它。
    浮动xScale等=((浮动)边界)/ W;
    浮动yScale =((浮动)边界)/小时;
    浮规模=(xScale等< = yScale)? xScale等:yScale;
    Log.i(测试,xScale等=+ Float.toString(xScale等));
    Log.i(测试,yScale =+ Float.toString(yScale));
    Log.i(测试,规模=+ Float.toString(规模));    //创建缩放的矩阵,并添加缩放数据
    字模=新的Matrix();
    matrix.postScale(秤,秤);    //创建一个新的位图,并将其转换成由理解的格式
    // ImageView的
    位图scaledBitmap = Bitmap.createBitmap(位图,0,0,W,H,矩阵
            真正);
    sWidth = scaledBitmap.getWidth(); //再利用
    sHeight = scaledBitmap.getHeight(); //再利用
    @燮pressWarnings(德precation)
    BitmapDrawable结果=新BitmapDrawable(scaledBitmap);
    Log.i(测试,缩放宽度=+ Integer.toString(sWidth));
    Log.i(测试,缩放高度=+ Integer.toString(sHeight));    返回scaledBitmap;
}

函数获取scaleImage边界值()函数

 私人诠释dpToPx(INT DP,诠释密度){
    INT结果= Math.round((浮点)DP *密度);
    返回结果;
}


解决方案

值您传递哪个到 dpToPx(INT的密度参数,INT)方法?

您的方法声明密度 INT ,这使我相信你可能会传递 DisplayMetrics.densityDpi ,三位数 INT 号码。你的意思使用 DisplayMetrics.density ,一个数字浮动号码。这将有外推32位图像尺寸:

 阈值的32位有符号整数= 2 ^ 31 -1 = 2147483647progressValue = 16
位图边= 16 * 128 = 2048
位图尺寸= 2048 ^ 2 = 4194304
在32 BPP = 4194304×32 = 134217728乘以densityDpi = 134217728 * 460 = 61740154880 // KABOOM
乘以密度= 134217728 * 3 = 402653184 // OK

I am scaling a Bitmap by using a seekbar. Whenever i increase the progress of seekbar, image scaling fails by giving error "Bitmap size exceeds 32bits". If i scale the image with default seekbar value. it gives an error "Illegal argument exception: Width and height must be > 0".

Log Report

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

Code snippet

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

Function to scale image in Class 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;
}

Function to get bounding value in scaleImage() function

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

解决方案

Which value are you passing into the density argument of your dpToPx(int,int) method?

Your method declares density as int, which leads me to believe you may be passing in DisplayMetrics.densityDpi, a three-digit int number. What you meant to use DisplayMetrics.density, a single digit float number. This will have pushed your image dimension outside 32 bits:

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

这篇关于位图大小超过32位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆