位图大小超过32位 [英] Bitmap size exceeds 32bits
问题描述
我使用搜索栏缩放位图。每当我增加搜索栏的进步,图像缩放给予错误位图大小超过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屋!