[英]MVC4 resize images to max height or max width
我正在创建 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;
}
}
如何调整图像大小以适应要求?
唯一的方法是裁剪人像照片以适合图像。 我有这个 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
谢谢爱德华多,你帮我找到了解决方案。 我修改了 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;
}
}
因此,如果图像具有纵向方向,则方法将其高度设置为所需高度并设置宽度保持纵横比,以便高度不能超过最大高度。 如果图像具有横向方法,则将宽度设置为想要的并设置高度保持纵横比。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.