0

我有下面的代码,我希望同时裁剪和调整大小,我使用下面的函数,我希望将 150 x 150 px 的图像大小居中裁剪,但如果图像宽度 > 高度,则始终使用下面的函数,输出图像将是 200x150,但我需要它是 150x150 像素,任何帮助

Function SavetoDisk(FU As FileUpload, ByVal para_Save_to_Path As String, ByVal maxHeight As Integer, ByVal maxWidth As Integer, para_FileExt As String, anchor As AnchorPosition)

    Using image As Image = image.FromStream(FU.PostedFile.InputStream)

        Dim sourceWidth As Integer = image.Width

        Dim sourceHeight As Integer = image.Height
        Dim sourceX As Integer = 0
        Dim sourceY As Integer = 0
        Dim destX As Integer = 0
        Dim destY As Integer = 0

        Dim nPercent As Decimal = 0
        Dim nPercentW As Decimal = 0
        Dim nPercentH As Decimal = 0

        nPercentW = (Convert.ToSingle(maxWidth) / Convert.ToSingle(sourceWidth))
        nPercentH = (Convert.ToSingle(maxHeight) / Convert.ToSingle(sourceHeight))

        If (nPercentH < nPercentW) Then
            nPercent = nPercentW
            Select Case (anchor)
                Case AnchorPosition.Top
                    destY = 0
                Case AnchorPosition.Bottom
                    destY = Convert.ToInt32(maxHeight - (sourceHeight * nPercent))
                Case Else
                    destY = Convert.ToInt32((maxHeight - (sourceHeight * nPercent)) / 2)
            End Select
        Else
            nPercent = nPercentH
            Select Case (anchor)
                Case AnchorPosition.Left
                    destX = 0
                Case AnchorPosition.Right
                    destX = Convert.ToInt32((maxWidth - (sourceWidth * nPercent)))
                Case Else
                    destX = Convert.ToInt32(((maxWidth - (sourceWidth * nPercent)) / 2))
            End Select
        End If

        Dim destWidth As Integer = Convert.ToInt32((sourceWidth * nPercent))
        Dim destHeight As Integer = Convert.ToInt32((sourceHeight * nPercent))

        Using thumbnailBitmap As Bitmap = New Bitmap(destWidth, destHeight)

            Using thumbnailGraph As Graphics = Graphics.FromImage(thumbnailBitmap)

                thumbnailGraph.CompositingQuality = CompositingQuality.HighQuality
                thumbnailGraph.SmoothingMode = SmoothingMode.HighQuality
                thumbnailGraph.InterpolationMode = InterpolationMode.HighQualityBicubic
                Dim imageRectangle As Rectangle = New Rectangle(0, 0, destHeight, destHeight)
                thumbnailGraph.DrawImage(image, New Rectangle(destX, destY, destWidth, destHeight), New Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), GraphicsUnit.Pixel)

                Dim jpegCodec As ImageCodecInfo = Findcodecinfo("JPEG")
                If Not IsNothing(jpegCodec) Then
                    Dim encoderParameters As EncoderParameters = New EncoderParameters(1)
                    encoderParameters.Param(0) = New EncoderParameter(Encoder.Quality, 80)
                    thumbnailBitmap.Save(para_Save_to_Path, jpegCodec, encoderParameters)
                Else
                    thumbnailBitmap.Save(para_Save_to_Path, ImageFormat.Jpeg)
                End If
            End Using

        End Using

    End Using

End Function
4

1 回答 1

0

实现您想要的步骤:

  1. 计算高宽比
  2. 将较大的尺寸缩小到 150 像素,将较小的尺寸缩小到比率 * 150 像素。
  3. 在 150x150 位图的中间绘制结果。

这段代码将完全做到这一点(c#):

using ( Image img = Image.FromStream( FU.PostedFile.InputStream ) )
{
    int sourceWidth = img.Width;
    int sourceHeight = img.Height;

    int desiredHeight = 150;
    int desiredWidth = 150;

    double heightToWidthRatio = sourceHeight / ( double )sourceWidth;

    //This draw method will always center the image horizonally or vertically, as appropriate
    using ( Bitmap thumbnailBitmap = new Bitmap( desiredWidth, desiredHeight ) )
    {
        using ( Graphics thumbnailGraph = Graphics.FromImage( thumbnailBitmap ) )
        {
            thumbnailGraph.CompositingQuality = CompositingQuality.HighQuality;
            thumbnailGraph.SmoothingMode = SmoothingMode.HighQuality;
            thumbnailGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;

            float destWidth = ( heightToWidthRatio > 1f ) ? ( float )( desiredWidth / heightToWidthRatio ) : desiredWidth;
            float destHeight = ( heightToWidthRatio > 1f ) ? desiredHeight : ( float )( desiredHeight * heightToWidthRatio );
            float destX = ( desiredWidth - destWidth ) / 2f;
            float destY = ( desiredHeight - destHeight ) / 2f;

            thumbnailGraph.DrawImage( img, new RectangleF( destX, destY, destWidth, destHeight ),
                                              new Rectangle( sourceWidth, sourceHeight, sourceWidth, sourceHeight ),
                                              GraphicsUnit.Pixel );
        }

    }
}

继续像以前一样写出文件。重要的部分是中间的四个浮点值,以及它在 DrawImage 函数中使用 RectangleF 来真正居中的事实,即使在小数值上也是如此。如果由于过度抗锯齿而不想要这种行为,只需 Math.Floor 值并继续使用 Rectangle 和 int。

于 2012-06-04T02:15:46.780 回答