2016-08-10 8 views
0

私は画像をアップロードできるMVCアプリケーションを持っており、最大サイズにリサイズされます。 50KB 私はwhileループでサイズ変更を行いますが、ファイルサイズが大きくなる画像の幅と高さを小さくすると問題になります。特定の時点で、サイズは小さくなるが、品質C# - 画像の解像度を下げるとファイルサイズが大きくなる

Request.InputStream.Position = 0; 
    string Data = new System.IO.StreamReader(Request.InputStream).ReadToEnd(); 
    var Base64 = Data.Split(',')[1]; 
    var BitmapBytes = Convert.FromBase64String(Base64); 
    var Bmp = new Bitmap(new MemoryStream(BitmapBytes)); 

    while (BitmapBytes.Length > 51200) 
    { 
     int Schritte = 20; //I tested here also with 300 
     int maxWidth = Bmp.Width; 
     maxWidth = maxWidth - Schritte; 
     int maxHeight = Bmp.Height; 
     maxHeight = maxHeight - Schritte; 
     Bmp = ScaleImage(Bmp, maxWidth, maxHeight); 
     var base64 = ReturnImageAsBase64(Bmp); 
     BitmapBytes = Convert.FromBase64String(base64); 
    } 

の費用でコードサイズを変更する:

public static Bitmap ScaleImage(Image image, int maxWidth, int maxHeight) 
{ 
    var ratioX = (double)maxWidth/image.Width; 
    var ratioY = (double)maxHeight/image.Height; 
    var ratio = Math.Min(ratioX, ratioY); 

    var newWidth = (int)(image.Width * ratio); 
    var newHeight = (int)(image.Height * ratio); 

    Bitmap newImage = new Bitmap(newWidth, newHeight); 
    using (Graphics gr = Graphics.FromImage(newImage)) 
    { 
     gr.SmoothingMode = SmoothingMode.HighQuality; 
     gr.InterpolationMode = InterpolationMode.HighQualityBicubic; 
     gr.PixelOffsetMode = PixelOffsetMode.HighQuality; 
     gr.DrawImage(image, new Rectangle(0, 0, newWidth, newHeight)); 
    } 
    return newImage; 
} 

私は66964バイトのサイズで始まります。ループの最初のターンの後、幅は300ピクセル、高さは420ピクセルであったものの、85151バイトとなりました。

+1

です。たとえば1bpp(黒または白)のBitmapを持ってScaleImageのnewImageに描画する場合、newImageはデフォルトのPixelformatで作成されます。これはColorsの可能性が高いため、24bppになります。その結果、メモリサイズがはるかに大きくなります。 –

答えて

0

以前の私のコメントから:

私はそれがあなたのピクセルフォーマットの問題であると言うでしょう。たとえば1bpp(黒または白)のBitmapを持ってScaleImageのnewImageに描画する場合、newImageはデフォルトのPixelformatで作成されます。これはColorsの可能性が高いため、24bppになります。その結果、メモリサイズがはるかに大きくなります。

は変更してみてください:

Bitmap newImage = new Bitmap(newWidth, newHeight); 

Bitmap newImage = new Bitmap(newWidth, newHeight, image.PixelFormat); 

に編集:インデックス付きPixelFormatsの使用からグラフィックスオブジェクトを作成することは不可能であるように見えるように、この上の簡単な解決策はないように思えます。

オリジナル画像:: 色ルックアップテーブル:

ここ
1 = Red = 255, 0,0 
2 = Black = 0, 0,0 
3 = Green = 0,255,0 
... 

     Column  
    Row 1 2 3 4 
     1 1 1 1 1 
     2 1 1 1 1 
     3 2 2 2 2 
     4 3 3 3 3 

あなたは16個のピクセルのための16のバイトとルックアップテーブルのための12バイトを持っている(1

は、より大きな画像サイズの理由を説明するために、インデックス番号の場合はバイト、各色のRGBチャネルの場合は3バイト) イメージの合計サイズは28バイトです

newImageでは、各ピクセルにはフルRGB情報:

  Column  
    Row 1   2   3   4 
     1 (255, 0,0) (255, 0,0) (255, 0,0) (255, 0,0) 
     2 (255, 0,0) (255, 0,0) (255, 0,0) (255, 0,0) 
     3 ( 0, 0,0) ( 0, 0,0) ( 0, 0,0) ( 0, 0,0) 
     4 ( 0,255,0) ( 0,255,0) ( 0,255,0) ( 0,255,0) 

のでNEWIMAGEの大きさは、私はそれがあなたのピクセルフォーマットの問題だと思います3 * 16 = 48バイト

+0

これは、新しいグラフィックを作成する次の行だけで例外をスローします。 (グラフィックスオブジェクトは、インデックス付きのピクセル形式を持つ画像から作成することはできません。) – Lexu

+0

これはGraphicsクラスの制限のようです。ここで参照してください:http://stackoverflow.com/questions/17313285/graphics-on-indexed-image –

+0

しかし、それは何が起こるかを完全に説明しています:元の画像には色のルックアップテーブルがあり、ピクセルは色のルックアップテーブルを指しています。新しいイメージでは、色はピクセルごとに1回保存されるので、イメージのサイズをさらに大きくする必要があります。 –

関連する問題