簡體   English   中英

在ASP.NET/C#中使用GDI +剪切圖像時是否抗鋸齒?

[英]Antialiasing when clipping an image using GDI+ in ASP.NET/C#?

我正在使用ASP.NET/C#/GDI+進行一些圖像轉換。 我有一個看起來像這樣的方法來使矩形圖像變圓:

public static Image MakeRound(Image img)
{
    Bitmap bmp = new Bitmap(img.Width, img.Height);

    GraphicsPath gp = new GraphicsPath();
    Graphics gr = Graphics.FromImage(bmp);

    using (gp)
    {
        gp.AddEllipse(0, 0, img.Width, img.Height);
        using (gr)
        {
            gr.SetClip(gp);
            gr.DrawImage(img, Point.Empty);
        }
    }
    return bmp;
}

它拍攝一個正方形圖像,然后添加一個與該圖像一樣大的橢圓。 然后,我使用SetClip刪除路徑外的所有內容並返回圓形圖像。 這按預期工作。

然后將返回的圖像在某個位置繪制到另一個(較大)圖像上,並將生成的合成圖像保存為文件。 如何使用此功能的真實示例可能是在現有圖像上添加徽標或水印。 這是此操作的一些代碼:

// Get backdrop image from server
string backdropPath = Server.MapPath("/img/backdrop.jpg");
System.Drawing.Image backdrop = Bitmap.FromFile(backdropPath);

// Create a graphics object to work with
Graphics gra = Graphics.FromImage(backdrop);
gra.DrawImage(MakeRound(smallerImage), new Point(50,50));

// Save the new image
backdrop.Save(saveFilePath);

唯一的問題是,疊加/倒圓/返回圖像的邊緣有些粗糙。 我想使其邊緣更平滑,使其與疊加的較大背景圖像更好地融合。

我可以使用任何抗鋸齒參數嗎? 您是否認為應該使用上述方法進行這種平滑處理,還是將圓形圖像疊加在較大的背景上時應用?

歡迎所有指針和技巧!

您正在尋找的技術稱為“羽化”,即:羽化邊緣是一種抗鋸齒的形式,應用於繪制圖像的邊緣。

看看GDI +中有關軟邊的文章。 它可能適用於您的方案。

您可以找到以下大多數示例:

  1. 使用畫筆繪制背景,或
  2. 使用SetClip刪除不需要的圖像部分

但是,如果您想要透明的背景,則兩者都有問題:

  1. 您不能使用透明筆刷繪制。 它什么也沒做。
  2. 正如您所注意到的, SetClip不會給您帶來抗鋸齒的優勢。

我發現這個答案很好用,但是這個答案只是為了解決問題而已,而不是圓成一個圓。 所以我修改了它。

這是將圖像裁剪為具有透明背景和抗鋸齒邊緣的圓的方法:

/// <summary>
/// Crop the given image into a circle (or ellipse, if the image isn't square)
/// </summary>
/// <param name="img">The image to modify</param>
/// <returns>The new, round image</returns>
private static Bitmap CropCircle(Image img) {
    var roundedImage = new Bitmap(img.Width, img.Height, img.PixelFormat);

    using (var g = Graphics.FromImage(roundedImage))
    using (var gp = new GraphicsPath()) {
        g.Clear(Color.Transparent);

        g.SmoothingMode = SmoothingMode.AntiAlias;

        Brush brush = new TextureBrush(img);
        gp.AddEllipse(0, 0, img.Width, img.Height);
        g.FillPath(brush, gp);
    }

    return roundedImage;
}

無需嘗試裁剪圖像,而是先創建一個新的透明圖像,然后在頂部繪制圖像的一部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM