2015-12-16 3 views
1

Я пытаюсь масштабировать исходное изображение до 50% и 25% и пытаюсь загрузить масштабированное изображение в MVC. Я использую приведенный ниже код, который был взят из поиска Google.Получение изображения большего размера при масштабировании C#

public byte[] ScaleImageByPercent(byte[] imageBuffer, int Percent) 
    { 

     using (Stream imageStream = new MemoryStream(imageBuffer)) 
     { 
      using (Image scaleImage = Image.FromStream(imageStream)) 
      { 
       float scalePercent = ((float)Percent/100); 

       int originalWidth = scaleImage.Width; 
       int originalHeight = scaleImage.Height; 
       int originalXPoint = 0; 
       int originalYPoint = 0; 

       int scaleXPoint = 0; 
       int scaleYPoint = 0; 
       int scaleWidth = (int)(originalWidth * scalePercent); 
       int scaleHeight = (int)(originalHeight * scalePercent); 

       using (Bitmap scaleBitmapImage = new Bitmap(scaleWidth, scaleHeight, PixelFormat.Format24bppRgb)) 
       { 
        scaleBitmapImage.SetResolution(scaleImage.HorizontalResolution, scaleImage.VerticalResolution); 
        Graphics graphicImage = Graphics.FromImage(scaleBitmapImage); 
        graphicImage.CompositingMode = CompositingMode.SourceCopy; 
        graphicImage.InterpolationMode = InterpolationMode.NearestNeighbor; 
        graphicImage.DrawImage(scaleImage, 
         new Rectangle(scaleXPoint, scaleYPoint, scaleWidth, scaleHeight), 
         new Rectangle(originalXPoint, originalYPoint, originalWidth, originalHeight), 
         GraphicsUnit.Pixel); 
        graphicImage.Dispose(); 

        ImageConverter converter = new ImageConverter(); 
        return (byte[])converter.ConvertTo(scaleBitmapImage, typeof(byte[])); 
       } 
      } 
     } 
    } 

Когда я использую 3.4MB изображения его возвращающийся 4.7Mb в 50%, а еще хуже в 100% его возвращении 18 МБ.

EDIT: После получения массива байтов я загружаю изображение, используя код ниже. После загрузки, когда я проверяю размер файла на диске, он показывает больший размер.

 HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); 
     result.Content = new StreamContent(new MemoryStream(scaledBytes)); 
     result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); 
     result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
     return result; 

Я делаю масштабирование правильно ?. Какой из них мне нужно изменить, получите изображение меньшего размера при масштабировании с использованием вышеуказанных функций.

+2

Вы сравниваете размер двух байтовых массивов или размер файла на диске? Имейте в виду, что когда вы загружаете JPG-файл, скажем, 500Kb, он распадается в памяти, что приводит к значительному массиву байтов (не менее 32 бит * ширина в пикселях * высота пикселей). Поэтому вы можете получить массив байтов размером «несколько мегабайт» из очень маленького JPG-файла (это может быть так, что вы видите с 100% -ным изменением размера). Это эффективно соответствует вашим значениям: процент 50% = итоговое изображение составляет 1/4 от оригинала, а 4.7Mb - 1/4 из 18Mb. –

+0

@Leo. Я сравниваю размер файла на диске. См. Мои правки. – Ramesh

+0

Я отправил вам ответ. Как я уже сказал, ваш код работает отлично, это вопрос сжатия изображения. Попробуйте, пожалуйста, дайте мне знать! –

ответ

1

Ваш код работает, я считаю, что это просто вопрос сжатия изображения, в основном вы подталкивая массив байтов в свой выходной поток как есть, в то время как вы должны сохранить его в формате JPEG , В моем примере я использую FileStream для простоты, в вашем случае вы должны использовать свой выходной поток. Дайте это попробовать (просто удалить любой файл Jpg на скомпилированный исполняемый файл):

using System; 
using System.Collections.Generic; 
using System.Drawing; 
using System.Drawing.Drawing2D; 
using System.Drawing.Imaging; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace ConsoleApplication3 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string filePath = System.IO.Path.GetFullPath(args[0]); 
      byte[] originalImage = System.IO.File.ReadAllBytes(filePath); 
      byte[] resizedImage = ScaleImageByPercent(originalImage, 50); 
      using (Stream imageStream = new MemoryStream(resizedImage)) 
      { 
       using (Image scaleImage = Image.FromStream(imageStream)) 
       { 
        string outputPath = System.IO.Path.GetDirectoryName(filePath); 
       outputPath = System.IO.Path.Combine(outputPath, $"{System.IO.Path.GetFileNameWithoutExtension(filePath)}_resized.jpg"); 
       using (FileStream outputFile = System.IO.File.Open(outputPath, FileMode.Create, FileAccess.Write)) 
       { 
        scaleImage.Save(outputFile, ImageFormat.Jpeg); 
       } 
      } 
     } 
    } 
    public static byte[] ScaleImageByPercent(byte[] imageBuffer, int Percent) 
    { 

     using (Stream imageStream = new MemoryStream(imageBuffer)) 
     { 
      using (Image scaleImage = Image.FromStream(imageStream)) 
      { 
       float scalePercent = ((float)Percent/100); 

       int originalWidth = scaleImage.Width; 
       int originalHeight = scaleImage.Height; 
       int originalXPoint = 0; 
       int originalYPoint = 0; 

       int scaleXPoint = 0; 
       int scaleYPoint = 0; 
       int scaleWidth = (int)(originalWidth * scalePercent); 
       int scaleHeight = (int)(originalHeight * scalePercent); 

       using (Bitmap scaleBitmapImage = new Bitmap(scaleWidth, scaleHeight, PixelFormat.Format24bppRgb)) 
       { 
        scaleBitmapImage.SetResolution(scaleImage.HorizontalResolution, scaleImage.VerticalResolution); 
        Graphics graphicImage = Graphics.FromImage(scaleBitmapImage); 
        graphicImage.CompositingMode = CompositingMode.SourceCopy; 
        graphicImage.InterpolationMode = InterpolationMode.NearestNeighbor; 
        graphicImage.DrawImage(scaleImage, 
         new Rectangle(scaleXPoint, scaleYPoint, scaleWidth, scaleHeight), 
         new Rectangle(originalXPoint, originalYPoint, originalWidth, originalHeight), 
         GraphicsUnit.Pixel); 
        graphicImage.Dispose(); 

        ImageConverter converter = new ImageConverter(); 
        return (byte[])converter.ConvertTo(scaleBitmapImage, typeof(byte[])); 
       } 
      } 
     } 
    } 
} 
} 

Вот это результат:

enter image description here

EDIT: Ok для интерфейса WebAPI попробовать сделать как это:

  HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); 

     using (Stream imageStream = new MemoryStream(resizedImage)) 
     { 
      using (Image scaleImage = Image.FromStream(imageStream)) 
      { 
       using (MemoryStream ms = new MemoryStream()) 
       { 
        scaleImage.Save(ms, ImageFormat.Jpeg); 
        result.Content = new StreamContent(ms); 
        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); 
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg"); 
       } 
      } 
     } 
     return result; 
1

Я думаю, мы сместим размер изображения путем изменения PixelFormat type.

Вы можете обратиться к этой Reducing Bitmap bit-size in C#

Смежные вопросы