Image Resize & Watermark — C# source
Batch-resize images by width, height or percentage and stamp a text watermark with position, opacity and size control — entirely in your browser, nothing uploaded.
This is the C# implementation — the same logic the interactive tool runs, in a shareable, citable form.
// Image Resize & Watermark — C# (.NET 8, System.Drawing) port of the image-resize-and-watermark tool.
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
namespace CosmoDev.ImageResizeAndWatermark;
public static class ImageResizeAndWatermark
{
// Mirrors the TS resizeAndWatermark: aspect-preserving resize, then a
// bottom-right watermark — white fill at 70% alpha over a dark outline
// (strokeText + fillText), both via one GraphicsPath.
public static Bitmap Run(Image src, int targetWidth, string watermark)
{
int h = (int)Math.Round((double)src.Height / src.Width * targetWidth, MidpointRounding.AwayFromZero);
var bmp = new Bitmap(targetWidth, h, PixelFormat.Format32bppArgb);
using (var g = Graphics.FromImage(bmp))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic; // imageSmoothingQuality 'high'
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.DrawImage(src, new Rectangle(0, 0, targetWidth, h));
int fs = (int)Math.Round(Math.Min(targetWidth, h) * 6.0 / 100.0);
// Bold ≈ the TS 600 weight; GenericSansSerif ≈ system-ui, sans-serif.
using var font = new Font(FontFamily.GenericSansSerif, fs, FontStyle.Bold, GraphicsUnit.Pixel);
var fmt = StringFormat.GenericTypographic; // unpadded measure, like measureText
var box = g.MeasureString(watermark, font, PointF.Empty, fmt);
// TS anchors the baseline at h-8; the path box top sits ~one ascent higher.
var origin = new PointF(targetWidth - box.Width - 8, h - 8f - font.Height);
var path = new GraphicsPath();
path.AddString(watermark, font.FontFamily, (int)FontStyle.Bold, fs, origin, fmt);
g.PixelOffsetMode = PixelOffsetMode.Default; // DrawPath centers the pen on the outline
using (var pen = new Pen(Color.FromArgb(140, 0, 0, 0), Math.Max(1f, fs / 14f))) // 0.55 alpha
g.DrawPath(pen, path); // strokeText
using var brush = new SolidBrush(Color.FromArgb(178, 255, 255, 255)); // 0.7 alpha
g.FillPath(brush, path); // fillText
}
return bmp;
}
public static void Main()
{
using var src = Image.FromFile("input.jpg");
using var result = Run(src, 1280, "CosmoDev");
// WebP needs ImageSharp/WPF on .NET 8; JPEG keeps the stdlib demo short.
result.Save("output.jpg", ImageFormat.Jpeg);
}
}
Also available in 8 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →