簡體   English   中英

最有效的水印圖像C#On the Fly?

[英]Most Efficient Way To Watermark Image C# On The Fly?

我有一個用asp.net c#(Webforms)構建的電子商務商店,很多新產品圖片很難找到,所以我想用我們的徽標或域名給它們添加水印。

有太多的產品只能下載圖像並添加水印,具有有限圖像編輯經驗的用戶將上傳新的(因此他們將不知道如何添加水印)。

所以我想這只是讓我使用HttpHandler? 是/否? 如果是這樣,你可以提供一些洞察力(最好是C#中的代碼樣本)到最有效的添加水印的方法,考慮到一些頁面將有大約20個圖像 (Jpegs)(所有這些都需要加水印)

我將獲取Graphics對象到jpeg,然后在該項目的頂部繪制水印,並使用水印再次保存:

using (Image image = Image.FromFile("myImage.jpg"))
using(Graphics g = Graphics.FromImage( image)){
  g.DrawImage( myWaterMarkImage, myPosition);
  image.Save(myFilename);
}

看起來它可能會有所幫助:

http://www.switchonthecode.com/tutorials/csharp-snippet-tutorial-how-to-draw-text-on-an-image

雖然它專注於文本,但我確信只需稍加修改即可添加圖形。

實現后,您可以在每個視圖中調用一次,也可以在保存文件之前添加。

這是一個示例HttpHandler

/// <summary>
/// Summary description for $codebehindclassname$
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class ImageHandler : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        string imageName = string.Empty;
        string physicalPath = string.Empty;
        Image image = null;
        Image thumbnailImage = null;
        Bitmap bitmap = null;
        using (MemoryStream memoryStream = new MemoryStream())
        {
            string actionName = context.Request.QueryString["Image"];
            string opacity = context.Request.QueryString["Opacity"];
            int opacityPercent = int.Parse(opacity);
            Color waterMarkColor = Color.Gray;
            switch (actionName)
            {
                case "BlueHills":
                    string myCompany = "My Company Name";
                    Font font = new Font("Times New Roman", 8f);

                    context.Response.ContentType = "image/png";
                    bitmap = Resources.Resources.BlueHills;
                    Graphics g = Graphics.FromImage(bitmap);
                    Brush myBrush = new SolidBrush(Color.FromArgb(opacityPercent, waterMarkColor));
                    SizeF sz = g.MeasureString(myCompany, font);
                    int X = (int)(bitmap.Width - sz.Width) / 2;
                    int Y = (int)(sz.Height) / 2;
                    g.DrawString(myCompany, font, myBrush, new Point(X, Y));
                    bitmap.Save(memoryStream, ImageFormat.Png);
                    break;
                default:
                    string test = actionName;
                    break;
            }

            context.Response.BinaryWrite(memoryStream.GetBuffer());
            memoryStream.Close();
            if (image != null) { image.Dispose(); }
            if (thumbnailImage != null) { thumbnailImage.Dispose(); }
            if (bitmap != null) { bitmap.Dispose(); }
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

並可以像這樣調用:

<asp:Image ID="Image1" runat="server" ImageUrl="~/ImageHandler.ashx?Image=BlueHills&Opacity=50" />

我建議你看看WPF類來完成這項工作(GDI +在Web上下文中已被棄用)。

方式(我不知道是不是最好的方式,但我已經完成了這個並且工作得非常好)類似於:

// Load the original image
BitmapImage image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = new Uri(physical_imagepath);
image.EndInit();

// Create a final render image
RenderTargetBitmap final = new RenderTargetBitmap(yourNeededWidth, yourNeededHeight, yourDpiDefault, yourDpiDefault, PixelFormats.Default);

DrawingVisual dv = new DrawingVisual();

using (DrawingContext dc = dv.RenderOpen())
{
    Rect rectImage = new Rect(0, 0, (double)image.PixelWidth, (double)image.PixelHeight);
    dc.DrawImage(image, rectImage);

    // Load the bitmap of the watermark
    BitmapImage watermark = new BitmapImage();
    watermark.BeginInit();
    watermark.CacheOption = BitmapCacheOption.OnLoad;
    watermark.UriSource = new Uri(physical_logopath);
    watermark.EndInit();

    // Defines the watermark box
    Rect rectWatermark = new Rect(0, 0, (double)watermark.PixelWidth, (double)watermark.PixelHeight);

    /* use rectWatermark.X and rectWatermark.Y to move your watermark box around on the final image */

    dc.DrawImage(watermark, rectWatermark);
}

final.Render(dv);

// And then serve the final Bitmap to the client

當然全都寫成HttpHandler。 上面的代碼未經過測試。

(小廣告:我發布了一個類似工作的CodeCanyon項目 )。

這不是一個答案,而是一些提示:

  1. Jpeg不支持透明度,你可以做的最好的事情是添加水印圖像並使其成為淺灰色。
  2. 使用通用處理程序(.ashx),它非常輕量級,可以防止您向web.config文件添加任何內容。
  3. 如果每頁最多有20張圖像,那么我會建議您在獲取圖像時添加水印。 這是每張圖像的一次性成本,並且可以使加載頁面的圖像更快。

我不能保證添加水印的最有效方法,但如果你使用#3提示,它就變得不那么重要了,因為你只會對每個圖像執行一次操作。 我可能只是使用System.Drawing命名空間來執行此操作; 請務必處理您使用的資源(圖像,圖形等),但我確信有些庫可以更好地工作。

任何“即時圖像標記”的明顯優化是,如果您能負擔得起存儲成本,則緩存“水印”圖像。 因此,wartermarking操作本身的效率並不重要。

暫無
暫無

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

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