[英]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项目 )。
这不是一个答案,而是一些提示:
我不能保证添加水印的最有效方法,但如果你使用#3提示,它就变得不那么重要了,因为你只会对每个图像执行一次操作。 我可能只是使用System.Drawing命名空间来执行此操作; 请务必处理您使用的资源(图像,图形等),但我确信有些库可以更好地工作。
任何“即时图像标记”的明显优化是,如果您能负担得起存储成本,则缓存“水印”图像。 因此,wartermarking操作本身的效率并不重要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.