我正在开发一个应用程序,在witch中我需要以BLOB格式存储超过1600张图像(.PNG)。每个图像的大小接近230KB。
我想做的是将图像压缩到20KB以下。因此,整个图像的大小将约为32MB(1600x20KB),最终的apk大小将会减小。
更多的解释:我想要做的是将图像从230KB压缩到20KB以下,以节省数据库中的更多空间。在集成到apk中之前,数据库中将填充数据和图像。
所以如果我压缩存储在数据库中的图像。数据库大小将会减小。并且它不会在APK中占用太多空间。
对如何做到这一点有什么建议吗?
注意:在集成到应用程序中之前,数据库中将填充信息。
发布于 2017-01-20 09:19:30
我认为最好将这些图像存储在服务器上,一旦用户下载了你的应用程序,你就应该将图像传输到应用程序中。在安装应用程序之前,1600真的是一个很大的数字……
发布于 2019-03-09 00:55:30
我不知道这是否是使用SQLite节省存储空间的最好方法,我仍然在寻找它,但我们开始吧。
您可以选择图像的来源,例如图库或相机,下面是代码。
private void selectProductImage() {
final CharSequence[] itens = {"Use Camera", "Gallery", "Cancel"};
AlertDialog.Builder builder = new AlertDialog.Builder(this,R.style.AlertDialog);
builder.setItems(itens, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (itens[which].equals("Use Camera")) {
Toast.makeText(YourActivity.this, "Use Camera", Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, MY_CAMERA_PERMISSION_CODE);
} else {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
} else if (itens[which].equals("Gallery")) {
Toast.makeText(YourActivity.this, "Gallery", Toast.LENGTH_SHORT).show();
Intent galleryIntent = new Intent();
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
startActivityForResult(galleryIntent, REQUEST_GALLERY_PHOTO);
} else if (itens[which].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}也许你需要得到许可才能使用相机
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == MY_CAMERA_PERMISSION_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Toast.makeText(this, "camera permission granted", Toast.LENGTH_LONG).show();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
} else {
Toast.makeText(this, "camera permission denied", Toast.LENGTH_LONG).show();
}
return;
}
}下面是如何处理来自您选择的源的图像。
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
Bitmap bitmap = Bitmap.createScaledBitmap((Bitmap) data.getExtras().get("data"),96, 96, true);
mProductImage.setImageBitmap(bitmap);
isPriviteImage = true;
}
if (requestCode == REQUEST_GALLERY_PHOTO && resultCode == RESULT_OK && data != null) {
//mProductImage.setImageURI(data.getData());
// INSERT IMAGE INTO SQLite
Uri uri = data.getData();
try {
InputStream inputStream = getContentResolver().openInputStream(uri);
Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(inputStream),96, 96, true);
mProductImage.setImageBitmap(bitmap);
isPriviteImage = true;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}正如您在我的示例中所注意到的,没有地方保存您选择的camera的图像案例,而我将图像放置在名为mProductImage.的ImageView变量中
从现在开始,您可以使用按钮将图像保存在SQLite数据库中。下面是你可以使用的函数。
private void saveImage() {
productTablePath = Environment.getExternalStorageDirectory()+"/YourAditionalPath/";
ProductDatabaseHelper productDatabaseHelper = new ProductDatabaseHelper(getApplicationContext(), "dbname.db", productTablePath);
productListTable = productDatabaseHelper.getWritableDatabase();
productRepository = new ProductRepository(productListTable);
try {
if (isPriviteImage) {
productRepository.addProduct(imageViewToByte(mProductImage));
isPriviteImage = false;
} else {
productRepository.addProduct(null);
}
mProductImage.setImageResource(R.drawable.shopping_cart_black_48dp);
} catch (Exception e) {
e.printStackTrace();
}
}其中imageViewToByte函数为:
private byte[] imageViewToByte(CircleImageView image) {
Bitmap bitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100,stream);
byte[] byteArray = stream.toByteArray();
return byteArray;
}现在,您需要实现SQLiteOpenHelper.您需要为此创建一个新类。为此,我使用的java文件名是ProductDatabaseHelper.java.
public class ProductDatabaseHelper extends SQLiteOpenHelper {
private static int dbVersion = 1;
public ProductDatabaseHelper(Context context, String name, String storageDirectory) {
super(context, storageDirectory+name, null, dbVersion);
}
@Override
public void onCreate(SQLiteDatabase db) {
StringBuilder sql = new StringBuilder();
sql.append("CREATE TABLE IF NOT EXISTS PRODUCTLIST (");
sql.append(" IMAGE BLOB,");
db.execSQL(sql.toString());
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}现在您需要实现CRUD (创建新项、读取、更新和删除)。
public class ProductRepository {
SQLiteDatabase instance;
public ProductRepository(SQLiteDatabase instance) {
this.instance = instance;
}
public void addProduct(byte[] image){
ContentValues contentValues = new ContentValues();
contentValues.put("IMAGE",image);
instance.insertOrThrow("PRODUCTLIST",null, contentValues);
}
}值得一提的是,对于源图像(相机和图库),图像的压缩都是在onActivityResult()中进行的。
使用以下命令:
Bitmap bitmap = Bitmap.createScaledBitmap(capturedImage, width, height, true);除此之外,这里有一个链接,我们可以在这里阅读一些关于压缩的内容。
https://androidwave.com/capture-image-from-camera-gallery/
如果您有更好的方法来压缩图像以保存在SQLite数据库中,请在此处发布您的代码!
https://stackoverflow.com/questions/41409259
复制相似问题