DEV Community

Cover image for ☁️ Powerful Cloud-Based Image Uploading with Watermark in .NET Core
hamza zeryouh
hamza zeryouh

Posted on

☁️ Powerful Cloud-Based Image Uploading with Watermark in .NET Core

☁️ 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);
Enter fullscreen mode Exit fullscreen mode

🔹 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");
Enter fullscreen mode Exit fullscreen mode

🔹 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);
Enter fullscreen mode Exit fullscreen mode

🔹 4. Delete by Public ID

Clean removal of uploaded files using Cloudinary's destroy API:

var result = await _cloudinary.DestroyAsync(new DeletionParams(publicId));
Enter fullscreen mode Exit fullscreen mode

📦 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);
}
Enter fullscreen mode Exit fullscreen mode

💡 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";
}
Enter fullscreen mode Exit fullscreen mode

📎 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.