2012-03-08 12 views
2

これはAndroidの質問です提供:アンドロイド - リサイズや写真に透かしを追加すると、低品質の画像

私はカメラで撮影したJPEG画像を撮ると私はに透かしを追加された後、640×480の解像度にそれをリサイズしています画像。このビットマップは、JPEGファイルに圧縮されて保存されます。

問題点は、下の例からわかるように、JPEGの画質がかなり低下していることです。最初のものはカメラで撮影したオリジナルのJPEGで、もう1つはサイズ変更された透かし入りのバージョンです。粒状性と色の不一致が最終的な画像に反映されていることがわかります。

また別の質問として、最終的なJPEG画像のサイズを縮小する方法はありますか? 640x480解像度のサムスンの携帯電話は約100KBのJPEGを配信しますが、下のコードを使用すると最終的なJPEGサイズは約250KBになります。 "Bitmap.CompressFormat.JPEG"の品質を70%に引き下げても、私は100KBにも達しません。

以下のコードを参照してください。

ソース画像形式のカメラ:http://www.freeimagehosting.net/ehtso

最終リサイズや透かし画像:http://www.freeimagehosting.net/qsxs6

public class AIS_PhotoResize { 

//resize photos to reduce data cost for sending photos 
public String ResizePhoto(String photoName) 
{  
    //folder location for existing photos 
    File oldFileRoot = new File(Environment.getExternalStorageDirectory() + File.separator + "AIS_Photos" + File.separator); 
    File oldFile = new File(oldFileRoot, photoName); 

    //folder location for resized photos 
    File newFileRoot = new File(Environment.getExternalStorageDirectory() + File.separator + "AIS_Photos" + File.separator + "Resized" + File.separator); 
    //ensure folder exist 
    newFileRoot.mkdirs(); 
    File newFile = new File(newFileRoot, photoName); 

    Bitmap b = null; 
    try { 
     //Decode image size 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 

     FileInputStream fis = new FileInputStream(oldFile); 
     BitmapFactory.decodeStream(fis, null, o); 
     fis.close(); 

     //The new size we want to scale to 
     final int IMAGE_MAX_SIZE=800; 

     int scale = 1; 
     if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) { 
      scale = (int)Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE/(double) Math.max(o.outHeight, o.outWidth))/Math.log(0.5))); 
     } 

     //Decode with inSampleSize 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize = scale;  
     o2.inPreferredConfig = Bitmap.Config.ARGB_8888; 
     o2.inScaled = false; 
     o2.inDither = true; 
     fis = new FileInputStream(oldFile); 
     b = BitmapFactory.decodeStream(fis, null, o2); 
     fis.close(); 

     //scale resized bitmap (version 1 - scaling using createScaledBitmap) 
     int scaledHeight = (int) (640/((float)b.getWidth()/(float)b.getHeight())); 
     Bitmap bScaled = Bitmap.createScaledBitmap(b, 640, scaledHeight, true); 
     b.recycle(); 

     /* 
     //scale resized bitmap (version 2 - scaling using matrix)    
     Matrix matrix = new Matrix(); 
     float desiredScale = 640/(float)b.getWidth(); 
     matrix.postScale(desiredScale, desiredScale); 
     Bitmap bScaled = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true); 
     //b.recycle(); 
     */ 

     //add timestamp watermark to photo 
     String watermark = photoName.substring(0, photoName.length() - 4); 
     Bitmap dest = Bitmap.createBitmap(bScaled.getWidth(), bScaled.getHeight(), Bitmap.Config.ARGB_8888); 
     Canvas cs = new Canvas(dest); 
     Paint tPaint = new Paint(); 
     tPaint.setTextSize(15); 
     tPaint.setColor(Color.RED); 
     tPaint.setStyle(Style.FILL); 
     tPaint.setAntiAlias(true); 
     Paint bScaledPaint = new Paint(); 
     bScaledPaint.setDither(true); 
     cs.drawBitmap(bScaled, 0f, 0f, bScaledPaint); 
     float height = tPaint.measureText("yY"); 
     cs.drawText(watermark, 5f, height+5f, tPaint); 
     bScaled.recycle(); 

     //encode scaled bitmap to jpeg 
     FileOutputStream out = new FileOutputStream(newFile); 
     dest.compress(Bitmap.CompressFormat.JPEG, 100, out); 

     //cleanup 
     dest.recycle(); 
     out.close(); 

     return "Success"; 

    } catch (IOException e) { 
     ErrorReporter.getInstance().handleException(e); 
     return "Error: " + e.toString(); 
    } 
} 
+0

a)2倍にスケーリングする - >品質低下b)ディザリングが悪く、ARGB_8888の場合は不要です。あなたはそれらを保存するときにどのようなステップがどのように見えるのかを確認しましたか?(いくつかの 'b.compress()'ステップを追加 - PNGは品質を確認することをお勧めします)? – zapl

+0

は透かしを入れていません。あなたは透かしを見るはずです。 – njzk2

答えて

0

私が画像の品質を向上させることはできませんよ、また私が削減できると思っているようです品質を維持してください。これはAndroidの限界です。

0

私のプロジェクトでは、ウォーターマークを写真にも撮りたいと思っています。あなたの作品を読んだ後で、私のプロジェクトの「メモリ不足」の問題が修正されました。 O(∩_∩)O ~~

関連する問題