【问题标题】:MVC4 resize images to max height or max widthMVC4 将图像大小调整为最大高度或最大宽度
【发布时间】:2016-03-23 21:59:54
【问题描述】:

我正在创建 MVC4 网站,并希望显示数据库中所有允许的图片。问题是图片有不同的大小,其中一些是纵向的,而另一些是横向的。首先,所有图像都需要保持纵横比。每个图像都显示在名为 card 的 div 中,并且它应该具有标准尺寸(我在 <img> 控件中设置的尺寸)。所以我需要以高度和宽度都不能超过<img>控件的尺寸高度和宽度的方式调整图像大小。例如,如果某些图像的纵向高度不得超过<img> 控件的高度,那么如果图像具有横向方向,则应以这种方式调整其大小,宽度不得超过<img> 控件的宽度。 我是这样展示图片的:

控制器

[ChildActionOnly]
    public ActionResult _PhotoGallery(int number)
    {
        List<Photo> photos;

        if (number == 0)
        {
            photos = context.FindAllUnVisiblePhotos(true).OrderByDescending(x => x.CreatedDate).ToList();
        }
        else
        {
            photos = context.FindAllUnVisiblePhotos(true).OrderByDescending(x => x.CreatedDate).Take(number).ToList();
        }

        return PartialView("_PhotoGallery", photos);
    }

查看

@foreach (var item in Model)
{
    <div class="photo-index-card">
        <div style="float:left; padding: 2px 2px 2px 2px; margin: 0px 0px 10px 0px; height: 20px;">
            <div>@item.Title</div>
        </div>

        <div style="float:left;">
            @if (item.PhotoFile != null)
            {
                <a href="@Url.Action("Display", "Photo", new { id = item.PhotoID })">
                    <img class="photo-index-card-img" src="@Url.Action("GetImage", "Photo", new { id = item.PhotoID })" />
                </a>
            }
        </div>                
    </div>
}

获取图片

public FileContentResult GetImage(int id)
    {
        Photo photo = context.FindPhotoById(id);
        if (photo.PhotoFile != null)
        {
            return File(photo.PhotoFile, photo.ImageMimeType);
        }
        else
        {
            return null;
        }
    }

如何调整图像大小以适应要求?

【问题讨论】:

    标签: c# asp.net-mvc-4 razor


    【解决方案1】:

    裁剪肖像照片以适合图像的唯一方法。我有这个 VB 函数,它完全按照你说的做,从顶部裁剪 25% 的额外高度像素,其余的从底部裁剪。大多数照片看起来都不错。我在旅游网站上使用它。

    Public Shared Function SaveAsThumbnailCropped(ByVal path As String, ByVal archivo As String, ByVal NewWidth As Integer, ByVal NewHeight As Integer) As String
    
        ' Declare two variables of type Integer named
        '    adjustedImageWidth and adjustedImageHeight.
        Dim adjustedImageWidth, adjustedImageHeight As Integer
    
        ' Declare a variable named theImage of type Image.
        Dim theImage As Image
        Dim ThumbFileName, extension As String, convertToGIF As Boolean = False
        If InStrRev(archivo, ".") > 0 Then
            extension = Mid(archivo, InStrRev(archivo, ".")).ToString.ToLower
            ThumbFileName = Mid(archivo, 1, InStrRev(archivo, ".") - 1) + "_tb" + Trim(NewWidth) + "x" + Trim(NewHeight) + extension
        Else
            extension = "" 'desconocida
            ThumbFileName = archivo + "_tb" + Trim(NewWidth) + "x" + Trim(NewHeight)
        End If
    
    
        If Not My.Computer.FileSystem.FileExists(path + "\" + ThumbFileName) And My.Computer.FileSystem.FileExists(path + "\" + archivo) Then
            ' Get an image object from the image file;
            '    assign the image object to the theImage variable.
            theImage = System.Drawing.Image.FromFile(path + "\" + archivo)
    
            If theImage.Height > NewHeight Or theImage.Width > NewWidth Then
                If theImage.Height * NewWidth / theImage.Width > NewHeight Then
                    ' tengo que reducir el alto
                    adjustedImageHeight = NewHeight
                    'keep ratio
                    adjustedImageWidth = theImage.Width * (adjustedImageHeight / theImage.Height)
                Else
                    adjustedImageWidth = NewWidth
                    'keep ratio
                    adjustedImageHeight = theImage.Height * (adjustedImageWidth / theImage.Width)
                End If
            Else
                'no hago nada porque la imagen es muy chica
                Return archivo
            End If
    
            Dim cropRect As Rectangle
            If adjustedImageHeight < NewHeight Or adjustedImageWidth > NewWidth Then
                'era muy apaisada tengo que croppear el centro
                adjustedImageHeight = NewHeight
                adjustedImageWidth = theImage.Width * (adjustedImageHeight / theImage.Height)
                Dim WidthSobrante = adjustedImageWidth - NewWidth
                cropRect = New Rectangle(WidthSobrante / 2, 0, NewWidth, NewHeight)
            ElseIf adjustedImageHeight > NewHeight Or adjustedImageWidth < NewWidth Then
                adjustedImageWidth = NewWidth
                adjustedImageHeight = theImage.Height * (adjustedImageWidth / theImage.Width)
                'quedo muy larga. Le cropeo el 25% de arriba del sobrante
                Dim HeightSobrante = adjustedImageHeight - NewHeight
                cropRect = New Rectangle(0, HeightSobrante / 4, NewWidth, NewHeight)
            Else
                cropRect = New Rectangle(0, 0, Math.Min(NewWidth, theImage.Width), Math.Min(NewHeight, theImage.Height))
            End If
    
            Dim Image As System.Drawing.Image = theImage
            Dim thumbnail As System.Drawing.Image = New Bitmap(adjustedImageWidth, adjustedImageHeight)
            Dim graphic As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(thumbnail)
    
            graphic.InterpolationMode = InterpolationMode.HighQualityBicubic
            graphic.SmoothingMode = SmoothingMode.HighQuality
            graphic.PixelOffsetMode = PixelOffsetMode.HighQuality
            graphic.CompositingQuality = CompositingQuality.HighQuality
    
            graphic.DrawImage(Image, 0, 0, adjustedImageWidth, adjustedImageHeight)
    
            Dim croppedThumbnail = cropImage(thumbnail, cropRect)
    
    
            If extension.Equals(".gif") Then
                Dim quantizer As ImageQuantization.OctreeQuantizer = New ImageQuantization.OctreeQuantizer(255, 8)
                Dim quantized As Bitmap = quantizer.Quantize(croppedThumbnail)
                quantized.Save(path + "\" + ThumbFileName, System.Drawing.Imaging.ImageFormat.Gif)
    
            ElseIf extension.Equals(".jpg") Or extension.Equals(".jpeg") Then
                'Create quality parameter
                Dim encoderParams As New EncoderParameters(1)
    
                Dim jpgCodec As ImageCodecInfo
                jpgCodec = GetImageCodec("image/jpeg")
    
                If Not jpgCodec Is Nothing Then
                    'Create quality parameter
                    Dim qParam As New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L)
                    encoderParams.Param(0) = qParam
                    croppedThumbnail.Save(path + "\" + ThumbFileName, jpgCodec, encoderParams)
                End If
            Else
                croppedThumbnail.Save(path + "\" + ThumbFileName)
            End If
    
            croppedThumbnail.Dispose()
            thumbnail.Dispose()
            Image.Dispose()
            graphic.Dispose()
    
        End If
    
        Return ThumbFileName
    
    
    End Function
    
    Private Shared Function cropImage(img As Image, cropArea As Rectangle) As Image
        Dim bmpImage = New Bitmap(img)
        Dim bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat)
        Return CType(bmpCrop, Image)
    End Function
    
    
    
    Private Shared Function GetImageCodec(ByVal mimeType As String) As ImageCodecInfo
        Dim codecs() As ImageCodecInfo = ImageCodecInfo.GetImageEncoders()
        For Each codec As ImageCodecInfo In codecs
            If codec.MimeType.Equals(mimeType, StringComparison.OrdinalIgnoreCase) Then
                Return codec
            End If
        Next
    
        Return Nothing
    End Function
    

    【讨论】:

      【解决方案2】:

      感谢 Eduardo,您帮助我找到了解决方案。 我修改了 GetImage 方法,以确保图像的每个维度都小于想要的维度。 代码比文字解释更多:

      public FileContentResult GetImage(int id, int w, int h)
          {
              Photo photo = context.FindPhotoById(id);
              MemoryStream ms;
              if (photo.PhotoFile != null)
              {
                  if (w != 0 && h != 0)
                  {
                      ms = new MemoryStream(photo.PhotoFile);
                      Image img = Image.FromStream(ms);
                      var ratio = (double)img.Width / (double)img.Height;
                      var ratioImg = (double)w / (double)h;
                      var newHeight = 0;
                      var newWidth = 0;
      
                      if (img.Height > img.Width)
                      {
                          newHeight = h;
                          newWidth = (int)(ratio * newHeight);
                      }
                      else
                      {
                          newWidth = w;
                          newHeight = (int)(newWidth / ratio);
                      }
      
                      var newImage = new Bitmap(newWidth, newHeight);
                      var destRect = new Rectangle(0, 0, newWidth, newHeight);
      
                      using (var graphics = Graphics.FromImage(newImage))
                      {
                          graphics.CompositingMode = CompositingMode.SourceCopy;
                          graphics.CompositingQuality = CompositingQuality.HighQuality;
                          graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                          graphics.SmoothingMode = SmoothingMode.HighQuality;
                          graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
      
                          using (var wrapMode = new ImageAttributes())
                          {
                              wrapMode.SetWrapMode(WrapMode.TileFlipXY);
                              graphics.DrawImage(img, destRect, 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, wrapMode);
                          }
                      }
      
                      Bitmap bmp = new Bitmap(newImage);
                      ImageConverter icnv = new ImageConverter();
      
                      var imgByte = (byte[])icnv.ConvertTo(bmp, typeof(byte[]));
      
                      return File(imgByte, photo.ImageMimeType);
                  }
                  else
                  {
                      return File(photo.PhotoFile, photo.ImageMimeType);
                  }                
              }
              else
              {
                  return null;
              }
          }
      

      因此,如果图像具有纵向方向,则方法将其高度设置为所需高度,并设置宽度以保持纵横比,以使高度不能超过最大高度。如果图像具有横向方法,则将宽度设置为想要的并设置高度保持纵横比。

      【讨论】:

        猜你喜欢
        • 2013-04-28
        • 1970-01-01
        • 1970-01-01
        • 2017-12-08
        • 1970-01-01
        • 2016-03-30
        • 2014-04-04
        • 2014-02-04
        • 2017-03-12
        相关资源
        最近更新 更多