有没有减小PNG文件大小的方法?

4

如何减小.png图像的大小?

将文件从drawable中复制到外部位置也会使文件大小增加5至10倍。

以下是一些相关的it技术:

bm.compress(Bitmap.CompressFormat.PNG, 50, out); //在这里,由于PNG是无损的,50不起作用

Bitmap bm=BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);

String extStorageDirectory = Environment.getExternalStorageDirectory().toString();

File file = new File(extStorageDirectory, "ic_launcher.PNG");
outStream = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();

做这件事情的意义是什么?(从drawable复制到外部) - Selvin
@selvin 也许有这样一种情况,你想把所有的可绘制PNG放在用户文件夹中,以便用户可以在其他应用程序中使用它们... :) - Electro
4个回答

5

1) 如果你的PNG是预定义的,你可以使用 Tiny PNG服务来获得非常小的PNG。该服务可以将PNG大小减少约60%,而不会有任何明显的变化。

2) 如果你的PNG是在运行时创建/获取的,请尝试使用 Bitmap.createScaledBitmap()方法。使用此方法,您可以创建小尺寸的PNG。

在该方法中,

bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);

100在PNG的情况下被忽略,因为它是无损的。相反,您可以使用

bm.compress(Bitmap.CompressFormat.JPEG, 80, outStream);

这个选项会让文件大小更小,同时压缩速度更快。

3
但是它会给你一个JPG文件,对吧?即使你保留相同的文件名和扩展名(.png),那个压缩调用中的数据将会是JPG格式。 - inlacou
如果您使用Bitmap.CompressFormat.JPEG - 是的。 - Arsen Sench

4

我知道这个问题有点老,但我仍然会为以后的搜索者提供答案。
Android的Bitmap类在压缩PNG方面非常有限。它只创建具有有限优化的PNG-32。打包apk文件的aapt程序会优化PNG文件。因此,当您将PNG文件解压缩并读入位图,然后使用位图类进行压缩时,您将得到一个更大的文件。
您可以使用支持更好的PNG文件压缩的pngj库。
但是根据您的描述,您似乎不会在应用程序中编辑文件,而只是从资源复制到卡片上,因此您需要做的就是将PNG文件包含在raw文件夹中,并通过调用openRawResource()检索到它的流,并直接将其复制到卡片上。您可以在将其包含在应用程序中之前使用TinyPNG进一步优化原始PNG文件。


0

你想严格使用PNG格式吗?Bitmap.compressFormat.JPEG可以压缩更多。

减小PNG文件大小的唯一方法是将PNG图像尺寸缩小到较小的尺寸。我认为这在纯Android中不是很直接,但是有一些可以用于此的图像库。

您还可以通过创建新的Bitmap对象并手动使用getPixels(...)从原始图像中读取,对其进行处理以进行降采样,并编写新的图像。但我不建议这样做,因为调整大小可能会很棘手,需要正确地使用抗锯齿技术。


0

您是否需要保持位图的质量不变?如果不需要,您可以通过bm.compress(Bitmap.CompressFormat.PNG, 50, outStream);来减小其大小。这里的50是被压缩的位图质量。另一个选项是在将位图加载到内存之前使用Bitmap.Option

BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = false;
    options.inSampleSize = 3;
    try{
        mBitmapImage = BitmapFactory.decodeFile(mPhotoPath.replace("file://" , ""), options);
    }catch(Exception e){
        e.printStackTrace();
        throw new OutOfMemoryError("Device Out of Memory, can't obtain Bitmap");
    }

如果您只想获取位图的大小,请设置options.inJustDecodeBounds = true。这有助于防止应用程序在运行时崩溃。

有关位图加载和压缩的更多信息,请参阅开发人员文档https://developer.android.com/topic/performance/graphics/load-bitmap

Bitmap类在压缩PNG方面并不是很有帮助。它只能创建具有有限优化的PNG-32。而aapt可以优化PNG文件。因此,当您将PNG文件解压缩并读入位图,然后使用位图类进行压缩时,您会得到一个更大的文件。
您可以使用pngj库,该库支持更好的PNG文件压缩和优化。
根据您的描述,您似乎不需要在应用程序中编辑文件,您只需从资源复制到卡中即可。因此,您只需要将PNG文件包含在raw文件夹中,并通过调用openRawResource()方法检索其流,然后直接将其复制到卡中。在将其包含在应用程序中之前,您还可以使用TinyPNG进一步优化原始PNG文件。

3
CompressFormat.PNG 会忽略质量设置为50。 - Eugene Kartoyev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接