2012-04-25 3 views
1

Я разрабатываю веб-сайт и нуждаюсь в большом размере большого размера в размере 400Wx264H без потери пропорции.изменить размер любого изображения в 400Wx264H с помощью C# для веб-приложения asp.net

Я работал над другой версией кода, но все возвращаются с той или иной проблемой.

Прямо сейчас я изменяю размеры больших изображений на 400 Вт при сохранении пропорций, а затем я разрешаю пользователю выбирать часть изображения с помощью jCrop, выбираемой области является 350Wx230H.

Проблема с этим иногда добавляет черную часть изображения, если высота изображения или ширина изображения меньше 400 Вт или 264 Н пикселей.

Буду признателен, если кто-то может указать мне на нечто похожее, что я должен делать.

КОД для загрузки и изменения размера изображений НИЖЕ

public void ResizeImageFreeSize(string OriginalFile, string NewFile, int NewWidth, int MaxHeight, bool OnlyResizeIfWider, string fileExtension) 
    { 
     System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(OriginalFile); 
     // Prevent using images internal thumbnail 
     //FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone); 
     //FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone); 
     //if (OnlyResizeIfWider) 
     //{ 
     // if (FullsizeImage.Width <= NewWidth) 
     // { 
     //  NewWidth = FullsizeImage.Width; 
     // } 
     //} 
     //int NewHeight = FullsizeImage.Height * NewWidth/FullsizeImage.Width; 
     //if (NewHeight > MaxHeight) 
     //{ 
     // // Resize with height instead 
     // NewWidth = FullsizeImage.Width * MaxHeight/FullsizeImage.Height; 
     // NewHeight = MaxHeight; 
     //} 
     System.Drawing.Image NewImage = FullsizeImage.GetThumbnailImage(NewWidth, MaxHeight, null, IntPtr.Zero); 
     // Clear handle to original file so that we can overwrite it if necessary 
     FullsizeImage.Dispose(); 
     // Save resized picture 

     if (fileExtension.ToLower() == ".jpg" || fileExtension.ToLower() == ".jpeg") 
     { 
      //NewImage.Save(NewFile, System.Drawing.Imaging.ImageFormat.Jpeg); 

      Encoder quality = Encoder.Quality; 
      var ratio = new EncoderParameter(quality, 100L); 
      var codecParams = new EncoderParameters(1); 
      codecParams.Param[0] = ratio; 
      NewImage.Save(NewFile, GetEncoder(ImageFormat.Jpeg), codecParams); 
     } 

     if (fileExtension.ToLower() == ".png") 
     { 
      NewImage.Save(NewFile, System.Drawing.Imaging.ImageFormat.Png); 
     } 

     if (fileExtension.ToLower() == ".gif") 
     { 
      NewImage.Save(NewFile, System.Drawing.Imaging.ImageFormat.Gif); 
     } 
    } 

выше кода загрузить большое изображение и повторно размер его к фиксированному размеру 400x264 пикселей. но этот подход растягивает изображение, поскольку у меня есть комментарии к коду, который поддерживает аспектный рацион.

После того, как загружено изображение размера изображения, я разрешаю пользователю выбирать область с этого изображения, используя jCrop, выбирается в 350x230 пикселей.

Это работает без каких-либо проблем, но изображения растягиваются

protected void btnCrop_Command(object sender, CommandEventArgs e) 
{ 
    cropImage(); 
    // pnlImageDetails.Visible = true; 
} 

protected void cropImage() 
{ 
    var x = int.Parse(_xField.Value); 
    var y = int.Parse(_yField.Value); 
    var width = int.Parse(_widthField.Value); 
    var height = int.Parse(_heightField.Value); 
    string _CropImagePath = Session["_CropImagePath"].ToString(); 
    using (var photo = System.Drawing.Image.FromFile(_CropImagePath)) 
    using (var result = 
      new Bitmap(width, height, photo.PixelFormat)) 
    { 
     result.SetResolution(photo.HorizontalResolution, photo.VerticalResolution); 
     using (var g = Graphics.FromImage(result)) 
     { 
      // g.InterpolationMode = InterpolationMode.HighQualityBicubic; 
      g.InterpolationMode = InterpolationMode.HighQualityBicubic; 
      g.DrawImage(photo, new Rectangle(0, 0, width, height), 
           new Rectangle(x, y, width, height), 
              GraphicsUnit.Pixel); 
      photo.Dispose(); 
      result.Save(_CropImagePath); 
      string filePath = _CropImagePath.ToString(); 
      System.IO.FileInfo f = new System.IO.FileInfo(filePath); 
      string fileExtension = f.Extension; 
      string fileName = f.Name; 
      string[] fNameArray = fileName.Split('.'); 
      string fileNewName = fNameArray[0] + "TN" + f.Extension; 
      Session["ArticleThumbnailImage"] = fileNewName; 
      string fileNewPath = Server.MapPath("../ImagesArticles/") + fileNewName; 
      ResizeImageFreeSize(filePath, fileNewPath, 170, 112, true, fileExtension); 
     } 

    } 
} 

ЧАСТЬ HTML код

<div id="ImageEditorFrame" style="width:800px; height:350px; float:left; "> 

    <div style="width:404px; height:268px; margin-left:160px; margin-top:10px; padding-top:1px; background-image:url('images/Scale.png'); background-repeat:no-repeat;"> 
     <div style="width:400px; height:264px; margin-left:3px; margin-top:2px; padding-top:1px; background-color:#f5f5f5;"> 
      <asp:Image runat="server" ID="_imageEditor" ImageUrl="" Visible="true" /> 

     </div> 
     <div style="margin-top:10px;"> 
     <asp:Button ID="btnCrop" runat="server" style="float:left;" Text=" Crop Image " Visible="False" oncommand="btnCrop_Command" /> 
     <input id="w" type="text" name="w" size="4" disabled="disabled"> 
     <input id="h" type="text" name="h" size="4" disabled="disabled">(350x230)<br /><br /> 
     <asp:Label ID="lblUplodedImgInfo" runat="server" Text=""></asp:Label> 
     </div> 
    </div> 


    <input type="hidden" runat="server" id="_xField" /> 
    <input type="hidden" runat="server" id="_yField" /> 
    <input type="hidden" runat="server" id="_widthField" /> 
    <input type="hidden" runat="server" id="_heightField" /> 



</div> 

var editorID = '<%= _imageEditor.ClientID %>'; 
jQuery(function() { 
    jQuery('#' + editorID).Jcrop({ 
     onChange: showCoords, 
     onSelect: showCoords, 
     setSelect: [0, 0, 350, 230], 
     allowResize: false 
    }); 
}); 

function showCoords(c) { 

    var xField = document.getElementById('<%= _xField.ClientID %>'); 
    var yField = document.getElementById('<%= _yField.ClientID %>'); 
    var widthField = document.getElementById('<%= _widthField.ClientID %>'); 
    var heightField = document.getElementById('<%= _heightField.ClientID %>'); 

    xField.value = c.x; 
    yField.value = c.y; 
    widthField.value = 350; 
    heightField.value = 230; 
    $('#w').val(c.w); 
    $('#h').val(c.h); 
} 

Screen Shot для идеи Screen Shot for idea

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

Буду признателен, если кто-то может помочь мне с этим кодом указать мне полный рабочий пример.

С уважением

+0

Вы в конечном счете просто пытаетесь создать эскизы с фиксированным размером 350x230? – MyItchyChin

ответ

0

Если я правильно понимаю, ваша конечная цель состоит в том, чтобы в конечном итоге получить миниатюру 350x230 пикселей, но вы хотите, чтобы пользователь мог выбрать растение на основе предварительного просмотра 400x264px. К сожалению, вы форсируете соотношение сторон при предварительном просмотре, поэтому вы получаете искажение. Если вы оцениваете размер 400x264px как минимум, вы можете создавать миниатюры на основе тех минут, которые не будут искажены.

public static void ResizeImageFreeSize(string OriginalFile, string NewFile, int MinWidth, int MinHeight, string FileExtension) 
{ 
    var NewHeight = MinHeight; 
    var NewWidth = MinWidth;   
    var OriginalImage = Image.FromFile(OriginalFile); 

    if (OriginalImage.Width < MinWidth || OriginalImage.Height < MinHeight) 
     throw new Exception(String.Format("Invalid Image Dimensions, please upload an image with minmum dimensions of {0}x{1}px", MinWidth.ToString(), MinHeight.ToString())); 

    // If the image dimensions are the same then make the new dimensions the largest of the two mins. 
    if (OriginalImage.Height == OriginalImage.Width) 
     NewWidth = NewHeight = (MinWidth > MinHeight) ? MinWidth : MinHeight; 
    else 
    { 
     if (MinWidth > MinHeight) 
      NewHeight = (int)(OriginalImage.Height * ((float)MinWidth/(float)OriginalImage.Width)); 
     else 
      NewWidth = (int)(OriginalImage.Width * ((float)MinHeight/(float)OriginalImage.Height)); 
    } 

    // Just resample the Original Image into a new Bitmap 
    var ResizedBitmap = new System.Drawing.Bitmap(OriginalImage, NewWidth, NewHeight); 

    // Saves the new bitmap in the same format as it's source image 
    FileExtension = FileExtension.ToLower().Replace(".",""); 

    ImageFormat Format = null; 
    switch (FileExtension) 
    { 
     case "jpg": 
      Format = ImageFormat.Jpeg; 
      break; 
     case "gif": 
      Format = ImageFormat.Gif; 
      break; 
     case "png": 
      Format = ImageFormat.Png; 
      break; 
     default: 
      Format = ImageFormat.Png; 
      break; 
    } 

    ResizedBitmap.Save(NewFile, Format); 


    // Clear handle to original file so that we can overwrite it if necessary 
    OriginalImage.Dispose(); 
    ResizedBitmap.Dispose(); 
} 
+0

@Myltchy: следующая строка «ResizedBitmap.Save (NewFile, Format); « Генерирует эту ошибку »Сообщение =« Общая ошибка произошла в GDI + ». – Learning

+0

Я отмечу, что вы отвечаете как правильно, как вы указали причину. Я сделал несколько изменений в вашем ответе, исходя из моего требования. Любой, кто нуждается в деталях, может ссылаться на мой ответ. – Learning

1

Вы можете либо сохранить пропорции или жесткое ограничение на размеры изображения, т.е. 400x264 Если вы хотите сохранить пропорции ваше новое изображение должно быть уменьшено на коэффициент min(finalWidth/orignalWidth, finalHeight/orignalHeight)

См

+0

Я сделал ту часть кода, о которой прокомментировал комментарий. Проблема заключается в том, что клиент хочет получить лучшее из обоих миров. Он не хочет потерять пропорции и загрузить изображение любого размера. Я не уверен, как я могу это достичь. В основном они не хотят, чтобы какое-либо задание по редактированию изображений выполнялось вручную с использованием какого-то программного обеспечения ... они хотите все функциональные возможности веб-приложения .. – Learning

1

@MyItchyChin Я использую его логики с некоторыми изменениями так что я буду отмечать свой ответ, как правильно и **

Я редактировал этот код, чтобы добавить две вещи, один я получаю сообщение об ошибке из-за к блокировке, поэтому я использовал MemoryStream, чтобы обойти проблему блокировки. Другая проблема с кодом заключалась в том, что он генерировал изображения с низким разрешением для JPG, так как я добавил бит кода. Остальная логика такая же, что я не изменил

public static void ResizeImageFreeSize(string OriginalFile, string NewFile, int MinWidth, int MinHeight, string FileExtension) 
{ 
    var NewHeight = MinHeight; 
    var NewWidth = MinWidth; 
    // var OriginalImage = System.Drawing.Image.FromFile(OriginalFile); // THis statlement alon with generate error as file is locked so -->//GDI+ keeps a lock on files from which an image was contructed. To avoid the lock, construct the image from a MemorySteam: 

    MemoryStream ms = new MemoryStream(File.ReadAllBytes(OriginalFile)); 
    var OriginalImage = System.Drawing.Image.FromStream(ms); 

    if (OriginalImage.Width < MinWidth || OriginalImage.Height < MinHeight) 
     throw new Exception(String.Format("Invalid Image Dimensions, please upload an image with minmum dimensions of {0}x{1}px", MinWidth.ToString(), MinHeight.ToString())); 

    // If the image dimensions are the same then make the new dimensions the largest of the two mins. 
    if (OriginalImage.Height == OriginalImage.Width) 
     NewWidth = NewHeight = (MinWidth > MinHeight) ? MinWidth : MinHeight; 
    else 
    { 
     if (MinWidth > MinHeight) 
      NewHeight = (int)(OriginalImage.Height * ((float)MinWidth/(float)OriginalImage.Width)); 
     else 
      NewWidth = (int)(OriginalImage.Width * ((float)MinHeight/(float)OriginalImage.Height)); 
    } 

    // Just resample the Original Image into a new Bitmap 
    var ResizedBitmap = new System.Drawing.Bitmap(OriginalImage, NewWidth, NewHeight); 

    // Saves the new bitmap in the same format as it's source image 
    FileExtension = FileExtension.ToLower().Replace(".", ""); 

    ImageFormat Format = null; 
    switch (FileExtension) 
    { 
     case "jpg": 
      Format = ImageFormat.Jpeg; 

      Encoder quality = Encoder.Quality; 
      var ratio = new EncoderParameter(quality, 100L); 
      var codecParams = new EncoderParameters(1); 
      codecParams.Param[0] = ratio; 
      // NewImage.Save(NewFile, GetEncoder(ImageFormat.Jpeg), codecParams); 
      ResizedBitmap.Save(NewFile, GetEncoder(ImageFormat.Jpeg), codecParams); 
      break; 
     case "gif": 
      Format = ImageFormat.Gif; 
      ResizedBitmap.Save(NewFile, Format); 
      break; 
     case "png": 
      Format = ImageFormat.Png; 
      ResizedBitmap.Save(NewFile, Format); 
      break; 
     default: 
      Format = ImageFormat.Png; 
      ResizedBitmap.Save(NewFile, Format); 
      break; 
    } 

    // ResizedBitmap.Save(NewFile, Format); 


    // Clear handle to original file so that we can overwrite it if necessary 
    OriginalImage.Dispose(); 
    ResizedBitmap.Dispose(); 
} 

private static ImageCodecInfo GetEncoder(ImageFormat format) 
{ 
    ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders(); 
    foreach (ImageCodecInfo codec in codecs) 
     if (codec.FormatID == format.Guid) 
      return codec; 
    return null; 
}