Android Bitmap保存到本地没有作用,怎么处理?

读取了一个图片,又新建了一个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并覆盖原图片:

  1. 将新建的Bitmap对象进行处理填充色彩:

该部分你已经实现,使用bmp.setPixel(x, y, Color.argb(a, r, g, b))方法填充色彩即可。

  1. 保存Bitmap文件

使用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,这样可以避免一些压缩导致的问题。你不需要删除原文件也不需要重新创建一个新文件,直接覆盖原文件即可。

  1. 重新加载Bitmap文件

加载Bitmap文件可以使用以下代码:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
Bitmap bmp = BitmapFactory.decodeFile(pic_url, options);

在这段代码中,使用了inMutable属性将Bitmap对象设置为可变。这样就可以直接通过Bitmap对象修改像素值。如果你使用了其他方式加载Bitmap文件,也需要将Bitmap对象设置为可变。

  1. 使用新的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()方法中处理权限请求的结果。

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^