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. 大きいサイズを 150px に縮小し、小さいサイズを比率 * 150px に縮小します。
  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 );
        }

    }
}

以前と同じように、ファイルの書き出しを続けます。重要な部分は、中央の 4 つの float 値と、DrawImage 関数で RectangleF を使用して、小数の値でも真に中央に配置することです。過度のアンチエイリアシングが原因でその動作が望ましくない場合は、値を Math.Floor にして、引き続き Rectangle と ints を使用します。

于 2012-06-04T02:15:46.780 に答える