【发布时间】:2021-10-30 15:10:31
【问题描述】:
保存到 SQLite 时如何限制图像的大小?当我检索我认为没有从 SQLite 获得大大小的 blob 图像时出现此错误。但是,我尝试在SELECT id,cash_card,hh_number,cc_image FROM CgList limit 500 这样的查询中设置限制 500,但结果是一样的,它使我的应用程序崩溃。
简而言之,有什么办法可以减少图片插入SQLite数据库时的文件大小?
错误
android.database.sqlite.SQLiteBlobTooBigException:行太大而无法容纳 进入 CursorWindow requiredPos=0, totalRows=4
插入数据和blob
public void insertData(String cash_card, String hh_number,String series_number ,byte[] cc_image,byte[] id_image){
SQLiteDatabase database = getWritableDatabase();
String sql = "INSERT INTO CgList VALUES (NULL,?, ?, ?, ?, ?)";
SQLiteStatement statement = database.compileStatement(sql);
statement.clearBindings();
statement.bindString(1, cash_card);
statement.bindString(2, hh_number);
statement.bindString(3, series_number);
statement.bindBlob(4, cc_image);
statement.bindBlob(5, id_image);
statement.executeInsert();
}
获取数据
Cursor cursor = ScannedDetails.sqLiteHelper.getData("SELECT id,cash_card,hh_number,cc_image FROM CgList");
list.clear();
while (cursor.moveToNext()) { // the error is here
int id = cursor.getInt(0);
String name = cursor.getString(1);
String price = cursor.getString(2);
byte[] image = cursor.getBlob(3);
list.add(new Inventory(name, price, image, id));
}
adapter.notifyDataSetChanged();
当我点击按钮保存到 SQLite 时
btnSubmit.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
sqLiteHelper.insertData(
edtCashCard.getText().toString().trim(),
edtHhnumber.getText().toString().trim(),
edtSeriesno.getText().toString().trim(),
imageViewToByte(mPreviewCashcard),
imageViewToByte(mPreview4PsId)
);
}
});
将图像转换为字节
public static byte[] imageViewToByte(ImageView image) {
Bitmap bitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
return byteArray;
}
更新
我认为这是捕获提供更大尺寸的图像时的问题,我需要这个,因为在捕获图像后,我想出于某种目的裁剪图像,但我想将实际捕获而不是裁剪的图像显示给另一个活动
private void pickCamera() {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "NewPic");
values.put(MediaStore.Images.Media.DESCRIPTION, "Image to Text");
image_uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,values);
Intent cameraIntent = new Intent (MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
startActivityForResult(cameraIntent, IMAGE_PICK_CAMERA_CODE);
}
OnActivityResult
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK){
if (requestCode == IMAGE_PICK_GALLER_CODE){
CropImage.activity(data.getData()).setGuidelines(CropImageView.Guidelines.ON).start(this);
}
if (requestCode == IMAGE_PICK_CAMERA_CODE){
CropImage.activity(image_uri).setGuidelines(CropImageView.Guidelines.ON).start(this);
}
}
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE){
CropImage.ActivityResult result = CropImage.getActivityResult(data);
if(resultCode ==RESULT_OK){
Uri resultUri = result.getUri();
resultUri.getPath();
mPreviewIv.setImageURI(resultUri);
BitmapDrawable bitmapDrawable = (BitmapDrawable)mPreviewIv.getDrawable();
Bitmap bitmap = bitmapDrawable.getBitmap();
TextRecognizer recognizer = new TextRecognizer.Builder(getApplicationContext()).build();
if(!recognizer.isOperational()){
Toast.makeText(this,"Error",Toast.LENGTH_SHORT).show();
}
else{
Frame frame = new Frame.Builder().setBitmap(bitmap).build();
SparseArray<TextBlock> items = recognizer.detect(frame);
StringBuilder sb = new StringBuilder();
for (int i = 0; i<items.size(); i++){
TextBlock myItem = items.valueAt(i);
sb.append(myItem.getValue());
sb.append("\n");
}
Intent i = new Intent(MainActivity.this, ScannedDetails.class);
//camera
i.putExtra("CashCardImage",image_uri.toString()); //This data pass to another activity
startActivity(i);
}
}
}
}
检索到另一个活动
Bundle extras = getIntent().getExtras();
String resultUri = extras.getString("CashCardImage");
Uri myUri = Uri.parse(resultUri);
mPreviewCashCard.setImageURI(myUri);
我在保存到 SQLITE 时尝试的另一个大小并不大,它只是 KIB,我认为问题出在第一个 PickCamera 但这些代码需要裁剪图像
private void pickCamera() {
Intent intent = new Intent(ScannedDetails.this, InventoryList.class);
startActivity(intent);
}
【问题讨论】:
-
顺便说一句。在 sqlite 中保留这么大的 blob 效率非常低(保存/获取)
-
@ArthurAttout 感谢您的回复,但我不明白那里的答案您能告诉我发生了什么,这是插入数据时的问题吗?
-
@snachmsm 感谢您的回复 有没有限制图片大小的方法?
-
我尝试了上面的第一个答案,它显示了图像,但问题是,有没有办法在保存到 SQLITE 时限制图像的大小? @Arthur Attout
标签: java android android-sqlite