有没有办法减少PNG的大小?

时间:2016-09-30 14:16:03

标签: android png image-compression

bm.compress(Bitmap.CompressFormat.PNG, 50, out); //here 50 will not work as PNG is lossless

如何减少.png图片大小? 还只是从可绘制的文件大小增加5到10倍来处理外部位置?

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();

4 个答案:

答案 0 :(得分:2)

1)如果你的png是预定义的,你可以使用tiny png服务来获得非常小的png。该服务正在将png大小减小约60%,没有任何明显的变化。 2)如果在运行时创建/获取了png,请尝试使用Bitmap.createScaledBitmap()方法。使用此方法,您可以创建小尺寸的png。

方法

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

在PNG的情况下,忽略

100。因为它无损。相反,你可以使用

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

这个会给你小尺寸,压缩得更快。

答案 1 :(得分:2)

您将保持位图的质量不变。对你有必要吗?如果不是这样,则可以将大小减小为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

答案 2 :(得分:1)

我知道这已经过时了,但我仍然会回答任何未来的寻求者 Android的Bitmap类在压缩PNG方面非常有限。它仅创建具有有限优化的PNG-32。包装你的apk文件的aapt程序确实优化了PNG文件。因此,当您解压缩并将PNG文件读入位图,然后使用位图类压缩它时,您将获得更大的文件。
您可以使用pngj库,它可以更好地压缩PNG文件 但根据您的描述,您似乎无法编辑应用程序中的文件,只需将资源从资源复制到卡中,因此您只需将PNG文件包含在raw文件夹中,然后检索通过调用openRawResource()并将其直接复制到卡片来获取流。您可以使用TinyPNG进一步优化原始PNG文件,然后再将其包含在您的应用中。

答案 3 :(得分:0)

你想严格遵守PNG吗? Bitmap.compressFormat.JPEG可以压缩更多。

减少PNG文件大小的唯一方法是将PNG图像尺寸缩小到更小的尺寸。我不认为这是纯粹的Android直接前进,但有可用于此的图像库。

您也可以自己编写它,方法是创建一个新的Bitmap对象,并使用getPixels(...)手动读取原始对象,将它们处理为缩减,然后编写新的。但是我不建议这样做,调整大小对于使用抗锯齿来正常工作非常棘手。