☁️ Powerful Cloud-Based Image Uploading with Watermark in .NET Core
Handling image uploads in web applications can get tricky — especially when you want to:
- Optimize images for size and performance
- Add a dynamic text watermark
- Upload to a cloud provider like Cloudinary
- Handle bulk uploads and deletions
- Ensure clean logging and error handling
In this post, I’ll walk you through a robust service I built using Cloudinary + .NET Core that solves all of that — with extensibility and performance in mind.
✅ Features of This Service
This service is designed to handle all major image workflows for a backend API:
- ✅ Upload a single image with optional watermark
- ✅ Upload multiple images in parallel
- ✅ Resize & optimize images before uploading
- ✅ Add custom watermark text (like branding)
- ✅ Delete images from Cloudinary
- ✅ Full logging and error reporting
- ✅ Adjustable watermark style and quality
⚙️ Key Technologies Used
- Cloudinary .NET SDK
-
System.Drawing
for image resizing and optimization - ASP.NET Core + Dependency Injection
-
ILogger
for clean logs -
IFormFile
for file handling in ASP.NET Core APIs
🧠 How It Works
🔹 1. Upload with Optimization
Before uploading, the image is:
- Read from the stream
- Resized based on predefined rules
- Saved as optimized JPEG with 90% quality
- Sent to Cloudinary using
ImageUploadParams
var optimizedStream = await ConvertAndOptimizeImage(file);
🔹 2. Add Watermark
You can define a custom watermark using Cloudinary's transformation API:
new Transformation()
.Overlay(new TextLayer("GOORFA.COM")
.FontFamily("Arial")
.FontSize(80)
.FontWeight("bold"))
.Gravity("center")
.Opacity(60)
.Color("#FFFFFF")
.Flags("layer_apply");
🔹 3. Upload Multiple Images in Parallel
Uses Task.WhenAll()
to efficiently upload many files at once:
var uploadTasks = files.Select(file => UploadImageAsync(file, folder));
await Task.WhenAll(uploadTasks);
🔹 4. Delete by Public ID
Clean removal of uploaded files using Cloudinary's destroy API:
var result = await _cloudinary.DestroyAsync(new DeletionParams(publicId));
📦 Sample Use Case
You can easily use this service in a controller like this:
[HttpPost("upload")]
public async Task<IActionResult> UploadImage(IFormFile file)
{
var result = await _imageUploadService.UploadImageWithTextWatermarkAsync(file);
return Ok(result.SecureUrl);
}
💡 Optimization Highlights
- Uses
System.Drawing
for high-quality resizing - Smart logic to scale down large images, skip resizing small ones
- Uses JPEG encoding with
ImageCodecInfo
for compression control - Clean architecture: interface-based service, separated config, reusable watermark logic
🔐 Watermark Configuration
You can easily tweak the watermark style using the WatermarkConfig
class:
public class WatermarkConfig
{
public string Text = "GOORFA.COM";
public string FontFamily = "Arial";
public int FontSize = 20;
public string Color = "#FFFFFF";
public int Opacity = 50;
public string Position = "center";
}
📎 Summary
This .NET Core service:
- Improves UX by compressing images
- Adds professional watermarks with ease
- Scales efficiently for bulk uploads
- Integrates tightly with Cloudinary's CDN
🔗 Want the full source code?
Let me know in the comments or DM me — I’ll be happy to share a GitHub repo or Gist if there's interest. 😊
#dotnet #cloudinary #aspnetcore #developer #imageupload #webapi #backend #goorfa #cloud
Top comments (2)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.