GDI + ошибка при загрузке нескольких изображений и создании миниатюр - PullRequest
0 голосов
/ 02 марта 2012

У меня есть страница загрузки изображений, которая прекрасно работает, когда я загружаю только файлы.

Я добавил функцию «Создать эскиз».Похоже, файловая система имеет дескриптор на изображениях, когда начинается процесс миниатюр.

Я получаю «неопределенную ошибку GDI +» только тогда, когда размер изображения превышает 250К.Когда размер файлов меньше 250 КБ, миниатюры создаются, как и ожидалось.

Какие есть варианты?Здесь есть элегантное решение?Я хочу что-то не хакерское.
Кроме того, я использую HttpFileCollection, чтобы мы могли загружать несколько изображений одновременно.Я пытался использовать .Dispose для создания миниатюр, но не удалось, прежде чем мы дойдем до этой точки.

public void Upload_Click(object Sender, EventArgs e)
{
 string directory = Server.MapPath(@"~\images\");
  HttpFileCollection hfc = Request.Files;
  for (int i = 0; i < hfc.Count; i++)
  {
    HttpPostedFile hpf = hfc[i];

    if (hpf.ContentLength > 0)
    {
      string fileName = hpf.FileName;
      fileName = fileName.Replace(" ", "");
      hpf.SaveAs(fileName);
      createThumbnail(fileName);
    }
  }
}

private void createThumbnail(string filename)
{
  Image image = Image.FromFile(filename);
  Image thumb = image.GetThumbnailImage(100,100, () => false, IntPtr.Zero);
  thumb.Save(filename);
  image.Dispose();
  thumb.Dispose();
 }

Ответы [ 2 ]

3 голосов
/ 02 марта 2012

Пожалуйста, дайте мне знать, если это работает лучше:

    public string ImageDirectory { get { return Server.MapPath(@"~\images\"); } }

    public void OnUploadClick(object sender, EventArgs e)
    {
        var files = HttpContext.Request.Files.AllKeys.AsEnumerable()
            .Select(k =>HttpContext.Request.Files[k]);

        foreach(var file in files)
        {
            if(file.ContentLength <= 0)
                continue;

            string savePath = GetFullSavePath(file);
            var dimensions = new Size(100, 100);

            CreateThumbnail(file,savePath,dimensions);
        }
    }

    private void CreateThumbnail(HttpPostedFile file,string savePath, Size dimensions)
    {
        using (var image = Image.FromStream(file.InputStream))
        {
            using (var thumb = image.GetThumbnailImage(dimensions.Width, dimensions.Height, () => false, IntPtr.Zero))
            {
                thumb.Save(savePath);
            }
        }
    }

    private string GetFullSavePath(HttpPostedFile file)
    {
        string fileName = System.IO.Path.GetFileName(file.FileName).Replace(" ", "");
        string savePath = System.IO.Path.Combine(this.ImageDirectory, fileName);
        return savePath;
    }

Редактировать -

Foreach должен был больше следовать этому шаблону:

var files = HttpContext.Request.Files.AllKeys.AsEnumerable()
                .Select(k =>HttpContext.Request.Files[k]);

foreach(var file in files)
{

}
0 голосов
/ 02 марта 2012

Вы можете попробовать этот код для создания миниатюр.

       MemoryStream ms = new MemoryStream(File.ReadAllBytes(path));
       Bitmap originalBMP = new Bitmap(ms);

       int maxWidth = 200;
       int maxHeight = 200;

       // Calculate the new image dimensions 
       int origWidth = originalBMP.Width;
       int origHeight = originalBMP.Height;
       double sngRatio = Convert.ToDouble(origWidth) / Convert.ToDouble(origHeight);

       // New dimensions
       int newWidth = 0;
       int newHeight = 0;
       try
       {
           // max 200 by 200

           if ((origWidth <= maxWidth && origHeight <= maxHeight) || origWidth <= maxWidth)
           {
               newWidth = origWidth;
               newHeight = origHeight;
           }
           else
           {
               // Width longer (shrink width)
               newWidth = 200;
               newHeight = Convert.ToInt32(Convert.ToDouble(newWidth) / sngRatio);
           }

           // Create a new bitmap which will hold the previous resized bitmap 
           Bitmap newBMP = new Bitmap(originalBMP, newWidth, newHeight);
           // Create a graphic based on the new bitmap 
           Graphics oGraphics = Graphics.FromImage(newBMP);

           // Set the properties for the new graphic file 
           oGraphics.SmoothingMode = SmoothingMode.AntiAlias;
           oGraphics.InterpolationMode = InterpolationMode.High;
           // Draw the new graphic based on the resized bitmap 
           oGraphics.CompositingQuality = CompositingQuality.HighSpeed;

           oGraphics.DrawImage(originalBMP, 0, 0, newWidth, newHeight);

           // Save the new graphic file to the server 
           EncoderParameters p = new EncoderParameters(1);
           p.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, 70);     // Percent Compression

           MemoryStream savedBmp = new MemoryStream();

           newBMP.Save(savedBmp, ImageCodecInfo.GetImageEncoders()[1], p);

                          // Once finished with the bitmap objects, we deallocate them. 
           originalBMP.Dispose();
           newBMP.Dispose();
           oGraphics.Dispose();
           savedBmp.Dispose();

Конечно, немного больше работы, но это дает вам больший контроль.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...