Bitmap compressé avec qualité=100 plus grande taille de fichier que l'original
J'essaie d'envoyer une image à un serveur. Avant de l'envoyer, je suis en réduisant sa taille et la qualité, puis de fixer la rotation de la question. Mon problème est que, après la rotation de l'image, lorsque je sauvegarde, le fichier est plus gros qu'avant. Avant de rotation de la taille a été 10092 et après la rotation est 54226
//Scale image to reduce it
Bitmap reducedImage = reduceImage(tempPhotoPath);
//Decrease photo quality
FileOutputStream fos = new FileOutputStream(tempPhotoFile);
reducedImage.compress(CompressFormat.JPEG, 55, fos);
fos.flush();
fos.close();
//Check and fix rotation issues
Bitmap fixed = fixRotation(tempPhotoPath);
if(fixed!=null)
{
FileOutputStream fos2 = new FileOutputStream(tempPhotoFile);
fixed.compress(CompressFormat.JPEG, 100, fos2);
fos2.flush();
fos2.close();
}
public Bitmap reduceImage(String originalPath)
{
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
o.inPurgeable = true;
o.inInputShareable = true;
BitmapFactory.decodeFile(originalPath, o);
//The new size we want to scale to
final int REQUIRED_SIZE = 320;
//Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) {
break;
}
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inPurgeable = true;
o2.inInputShareable = true;
o2.inSampleSize = scale;
Bitmap bitmapScaled = null;
bitmapScaled = BitmapFactory.decodeFile(originalPath, o2);
return bitmapScaled;
}
public Bitmap fixRotation(String path)
{
Bitmap b = null;
try
{
//Find if the picture is rotated
ExifInterface exif = new ExifInterface(path);
int degrees = 0;
if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("6"))
degrees = 90;
else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("8"))
degrees = 270;
else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("3"))
degrees = 180;
if(degrees > 0)
{
BitmapFactory.Options o = new BitmapFactory.Options();
o.inPurgeable = true;
o.inInputShareable = true;
Bitmap bitmap = BitmapFactory.decodeFile(path, o);
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
mtx.postRotate(degrees);
b = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}
}
catch(Exception e){e.printStackTrace();}
return b;
}
OriginalL'auteur Pablo Moncunill | 2013-03-04
Vous devez vous connecter pour publier un commentaire.
Vous êtes à la compression avec différentes mesures de la qualité. Après la rotation, vous êtes à l'aide de la qualité de l'100, donc il va y avoir un fichier plus volumineux que le précédent, avec la qualité de l'55.
Lorsque vous compresser une image, il n'a pas d'importance ce que la taille actuelle du fichier/qualité. Qui n'a pas de réel impact sur le résultat. La compression à 55 de la qualité, suivi par 100 de la qualité, ne pas résultat dans un fichier avec la même taille qu'un simple 55 de la qualité de la compression. Il en résulte un fichier avec la taille de 100 de la qualité de compression, parce que c'est la dernière chose à faire pour elle.
Pour votre code, je ne suis pas sûr que je vois la raison derrière la compression deux fois de toute façon. Compression(taille du fichier) n'est pas ce qui a été à l'origine de votre OOM des problèmes lors de la rotation, les dimensions de l'image ont été probablement le coupable. Rétrécissement de l'image avant de la rotation devrait corriger cela, pas besoin pour l'enregistrement d'un fichier temp.
Tout ce que vous devez faire est d'exécuter
reduceImage()
, puis suivi defixRotation()
. Fixer votre méthode de rotation de sorte qu'il accepte unBitmap
au lieu d'un chemin, de sorte que vous n'avez pas besoin d'enregistrer le fichier dans entre. Enfin, enregistrer/compresser de manière à ce que la qualité que vous désirez.Si vous ne besoin du fichier temporaire pour une raison quelconque, utilisez le format PNG pour la première compression. De cette façon, il est sans perte, donc quand vous recompresser l'image finale, vous n'aurez pas utilisé JPG(avec perte de qualité) deux fois à une faible qualité.
Grâce Geobits, je pense que je suis le comprendre maintenant.Est-il un moyen afin que je puisse corriger les problèmes de rotation, de réduire sa taille et la qualité, sans avoir un fichier final plus grand que l'original? J'ai essayé de faire la première rotation, puis la réduction de la taille et la qualité, mais il m'a donné OutOfMemoryException lors de la rotation. Des idées?
Ajouté à répondre
OriginalL'auteur Geobits