读取了一个图片,又新建了一个bitmap,然后使用bmp.setPixel(x, y, Color.argb(a, r, g, b))将新建的bitmap色彩填满,然后想要用新建图片保存覆盖原图片。
Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
使用如下方法保存,运行没问题,但是打开图片发现,新图片并没有覆盖原图片。读写权限没问题
FileOutputStream fos = new FileOutputStream(pic_url);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
又尝试使用如下字节流的方法保存,保存后直接图片无法读取了
byte pixels[] = new byte[bmp.getWidth() * bmp.getHeight() * 4];
bmp.copyPixelsToBuffer(ByteBuffer.wrap(pixels));
File bmpfile = new File(pic_url);
if (bmpfile.exists()) {
bmpfile.delete();
bmpfile.createNewFile();
}
FileOutputStream fos = new FileOutputStream(bmpfile);
fos.write(pixels);
fos.close();
重新读取图片时出现如下报错:
2023-03-02 23:17:27.181 12019-12019/com.example.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 12019
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference
请问如何才能有效保存覆盖原图片?
确保 pic_url 指向的是原始图片的路径,即确保使用了正确的路径。
确保在保存前调用了 bmp.setPixel(x, y, Color.argb(a, r, g, b)),以填充 bmp。
如果你的原始图片是 JPEG 格式,那么在保存时应该使用 Bitmap.CompressFormat.JPEG 格式。如果原始图片是 PNG 格式,则应该使用 Bitmap.CompressFormat.PNG 格式。
确保保存时不要忘记调用 flush() 和 close() 方法。
如果使用了字节流保存方法,可以尝试使用 bmp.copyPixelsToBuffer(ByteBuffer.wrap(pixels)) 将 bmp 的像素数据写入到 pixels 数组中。
最后,你可以尝试在保存完成后检查是否保存成功,并手动将新图片复制到原始图片的路径,以确保覆盖原图片。
以下是一个Java示例代码,可能会有所帮助:
// 读取原图片
Bitmap bitmap = BitmapFactory.decodeFile(pic_url);
// 创建一个新的bitmap,并填充颜色
Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
for (int y = 0; y < bitmap.getHeight(); y++) {
for (int x = 0; x < bitmap.getWidth(); x++) {
bmp.setPixel(x, y, Color.argb(a, r, g, b));
}
}
// 保存新图片并覆盖原图片
FileOutputStream fos = new FileOutputStream(pic_url);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
你好,望采纳,由于安卓系统版本的问题,覆盖原图基本上无法实现了,除非您用的是低版本系统。
你可以先删除原图,然后保存成和原图一样的大小宽高,一样的文件名。
望采纳。
您可以尝试使用以下代码来保存并覆盖原始图像:
FileOutputStream fos = new FileOutputStream(pic_url);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.getFD().sync(); // 同步输出流
fos.close();
在保存完成后,调用getFD().sync()方法来同步输出流,这将确保将所有数据都写入文件中。这样应该可以解决您的问题并覆盖原始图像。
回答不易,还请能够采纳!!!
如果Android Bitmap保存到本地没有作用,可能有以下几种原因和解决方法:
文件路径错误:在保存Bitmap时,需要指定正确的保存路径。可以使用Log等方式查看保存路径是否正确,并检查路径是否存在和是否具有写入权限。
Bitmap为空:在保存Bitmap时,需要确保Bitmap不为空,否则会导致保存失败。可以使用Log等方式检查Bitmap是否正确加载和处理。
Bitmap格式不支持:在保存Bitmap时,需要确保Bitmap的格式是支持的。例如,JPEG格式需要使用Bitmap.compress()方法进行保存,而PNG格式可以直接使用Bitmap的writeToStream()方法进行保存。可以根据具体的Bitmap格式进行相应的处理。
内存限制:在保存Bitmap时,需要确保内存充足。如果Bitmap过大,可能会导致内存不足,保存失败。可以尝试使用Bitmap的inSampleSize属性进行缩放,或者使用Bitmap的recycle()方法释放内存。
异步处理:在保存Bitmap时,可以考虑使用异步处理的方式,避免阻塞UI线程。可以使用AsyncTask等方式进行异步处理,并在处理完成后进行保存。
如果以上方法无法解决问题,可以尝试使用第三方库进行Bitmap保存,例如Glide或Picasso等。这些库提供了更加简单和方便的Bitmap保存方法,可以减少开发难度和错误率。
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
针对你的问题,可以考虑使用以下步骤保存Bitmap并覆盖原图片:
该部分你已经实现,使用bmp.setPixel(x, y, Color.argb(a, r, g, b))
方法填充色彩即可。
使用FileOutputStream
保存Bitmap文件:
FileOutputStream out = null;
try {
out = new FileOutputStream(new File(pic_url));
bmp.compress(Bitmap.CompressFormat.PNG, 100, out); // 保存Bitmap的格式为PNG,你也可以保存为JPEG或者WEBP等其他格式
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
在保存文件时,可以将文件格式设置为PNG,这样可以避免一些压缩导致的问题。你不需要删除原文件也不需要重新创建一个新文件,直接覆盖原文件即可。
加载Bitmap文件可以使用以下代码:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
Bitmap bmp = BitmapFactory.decodeFile(pic_url, options);
在这段代码中,使用了inMutable
属性将Bitmap对象设置为可变。这样就可以直接通过Bitmap对象修改像素值。如果你使用了其他方式加载Bitmap文件,也需要将Bitmap对象设置为可变。
在重新加载Bitmap对象之后,就可以直接使用Bitmap对象进行像素处理了:
bmp.setPixel(x, y, Color.argb(a, r, g, b));
最后重新保存Bitmap即可。
完整的代码示例如下:
// 加载Bitmap对象
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
Bitmap bmp = BitmapFactory.decodeFile(pic_url, options);
// 处理Bitmap像素
for (int x = 0; x < bmp.getWidth(); x++) {
for (int y = 0; y < bmp.getHeight(); y++) {
bmp.setPixel(x, y, Color.argb(a, r, g, b));
}
}
// 保存Bitmap文件
FileOutputStream out = null;
try {
out = new FileOutputStream(new File(pic_url));
bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
希望这些代码可以帮助到你。
如果我的回答解决了您的问题,请采纳!
如果在Android中保存Bitmap到本地没有作用,可以尝试使用以下代码:java// 保存Bitmap到本地文件FileOutputStream fos = null;try { fos = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); fos.flush(); fos.close();} catch (IOException e) { e.printStackTrace();}// 通知媒体库更新MediaScannerConnection.scanFile(context, new String[]{file.toString()}, null, null);
这个代码块将Bitmap保存到本地文件,并使用MediaScannerConnection通知媒体库进行更新。这样可以确保保存的文件能够被系统正确识别和访问。如果仍然无法保存Bitmap到本地,可能是因为应用程序没有写入外部存储的权限。在AndroidManifest.xml文件中添加以下代码以请求权限:xml<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
请注意,在Android 6.0及以上版本中,您还需要在运行时请求权限。可以使用以下代码:javaif (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_WRITE_EXTERNAL_STORAGE);}
其中REQUEST_CODE_WRITE_EXTERNAL_STORAGE
是一个整数值,用于唯一标识此权限请求。您需要在onRequestPermissionsResult()
方法中处理权限请求的结果。