Android存入SQLite后ImageView图片模糊问题及清晰度优化咨询
解决SQLite存图后ImageView模糊问题及Drawable尺寸设置方案
一、图片模糊的根源与解决方法
你当前的核心问题是从相机Intent的data.getExtras().get("data")获取的是低分辨率缩略图,源图本身像素信息不足,不管怎么缩放或压缩都会模糊。直接设置更大尺寸只会让像素拉伸失真,必须从获取高分辨率原图入手:
1. 获取相机拍摄的原始大图
放弃用data.getExtras().get("data")拿缩略图,改为指定路径让相机保存原图:
// 创建临时文件用于保存原图 private File createImageFile() throws IOException { String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); return File.createTempFile(imageFileName, ".jpg", storageDir); } // 启动相机时指定输出Uri File photoFile = createImageFile(); Uri photoUri = FileProvider.getUriForFile(this, "com.yourapp.fileprovider", photoFile); Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
在onActivityResult中从文件路径加载原图:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { Bitmap bitmap = BitmapFactory.decodeFile(photoFile.getAbsolutePath()); // 后续处理显示与存储 } }
2. 优化图片存储到SQLite
- 优先建议存储图片文件路径而非直接存字节数组,避免数据库体积过大;
- 若必须存BLOB字段,用高质量压缩(PNG为无损压缩,质量参数无效;JPEG建议设为80-90):
ByteArrayOutputStream stream = new ByteArrayOutputStream(); // JPEG高质量压缩,PNG可替换为Bitmap.CompressFormat.PNG,质量参数随便设 bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream); byte[] imageBytes = stream.toByteArray(); // 将imageBytes存入SQLite的BLOB字段
3. 显示时的内存与清晰度优化
直接加载原图会导致内存溢出,需根据ImageView实际尺寸采样缩放:
// 获取ImageView的目标宽高 int targetWidth = imgAdditionalId.getWidth(); int targetHeight = imgAdditionalId.getHeight(); // 计算采样率,避免加载过大Bitmap BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(photoFile.getAbsolutePath(), options); int sampleSize = calculateInSampleSize(options, targetWidth, targetHeight); options.inJustDecodeBounds = false; options.inSampleSize = sampleSize; Bitmap scaledBitmap = BitmapFactory.decodeFile(photoFile.getAbsolutePath(), options); imgAdditionalId.setImageBitmap(scaledBitmap);
辅助采样率计算方法:
private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfHeight = height / 2; final int halfWidth = width / 2; while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) { inSampleSize *= 2; } } return inSampleSize; }
二、通过Drawable设置图片尺寸的三种方法
1. 代码中动态设置Bounds
直接指定Drawable的像素宽高:
Drawable drawable = getResources().getDrawable(R.drawable.your_image); // 设置左上右下四个边界,这里宽374px、高540px drawable.setBounds(0, 0, 374, 540); imgAdditionalId.setImageDrawable(drawable);
2. 使用ScaleDrawable缩放
通过比例缩放原图,需设置Level才会生效:
Drawable originalDrawable = getResources().getDrawable(R.drawable.your_image); // 以中心为基准,缩放到原图的50%宽高 ScaleDrawable scaleDrawable = new ScaleDrawable(originalDrawable, Gravity.CENTER, 0.5f, 0.5f); imgAdditionalId.setImageDrawable(scaleDrawable); scaleDrawable.setLevel(10000); // Level范围0-10000,10000为完全显示
3. XML中定义Drawable尺寸
用layer-list包装Drawable,指定dp单位的宽高:
<!-- res/drawable/scaled_image.xml --> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/your_image" android:width="374dp" android:height="540dp"/> </layer-list>
在ImageView中引用:
<ImageView android:id="@+id/imgAdditionalId" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/scaled_image"/>
内容的提问来源于stack exchange,提问作者marivic valdehueza
相关产品推荐
相关产品推荐

