در عصر دیجیتال امروز، مدیریت تصویر کارآمد برای برنامه های وب و APIs حیاتی است. یکی از جنبه های کلیدی مدیریت تصاویر فشرده سازی است، که به کاهش اندازه فایل بدون تضعیف قابل توجهی در کیفیت کمک می کند. این راهنمای شما را از طریق ساخت یک API فاش تصویر پویا با استفاده از Aspose.Imaging برای .NET راه می رود. در نهایت، شما یک ASP.NET Core Web API عملکردی خواهید داشت که تصاویر را می پذیرد و خروجی فاسد را با توجه به پارامترهای جستجو (فرمت، کیفیت، بازسازی و بیشتر) باز می گرداند.
Aspose.Imaging یک کتابخانه قدرتمند برای کار با تصاویر در .NET است که از بسیاری از فرمت ها پشتیبانی می کند و ویژگی های دستکاری قوی را فراهم می کنند، از جمله جریان های کاری از دست رفته (JPEG) و بدون زیان (PNG).
چه چیزی بسازید
- نقطه نهایی :
POST /api/images/compress?format=jpeg&quality=75&maxWidth=1280&maxHeight=1280
- نقطه نهایی :
- ** واردات**: فایل چند قسمت (تصویر)، پارامترهای پرس و جو اختیاری برای فرمت / کیفیت / اندازه
- ** خروجی ها**: جریان تصویر فشرده با صحیح
Content-Type
برچسب ها: caching headers - امنیت: اعتباربخشی نوع محتوا، محدودیت های اندازه و رمزگذاری ذخیره شده
پیش شرط
- .NET 8 (یا .Net 6+)
- نرم افزار ASP.NET Core Web API
- نوکیا :
Aspose.Imaging
- اختیاری: شروع مجوز در اپلیکیشن استارتاپ (اگر شما از یک ساختمان مجاز استفاده می کنید)
ساختار پروژه (محدود)
/Controllers
ImageController.cs
/Services
ImageCompressionService.cs
/Models
CompressionRequest.cs
Program.cs
appsettings.json
نمونه کامل (Service + Controller)
جایگزین فضاهای نامی میزبان با فضای نام پروژه خود باشید.
/Models/CompressionRequest.cs
namespace ImageApi.Models;
public sealed class CompressionRequest
{
// "jpeg" or "png"
public string Format { get; init; } = "jpeg";
// 1..100 (applies to JPEG only; PNG is lossless)
public int? Quality { get; init; } = 80;
// Optional resize bounds; image is resized preserving aspect ratio if either is provided.
public int? MaxWidth { get; init; }
public int? MaxHeight { get; init; }
// If true, strip metadata (EXIF, IPTC) where applicable to reduce size further.
public bool StripMetadata { get; init; } = true;
// Guardrails
public void Validate()
{
var fmt = Format?.ToLowerInvariant();
if (fmt is not "jpeg" and not "png")
throw new ArgumentException("Unsupported format. Use 'jpeg' or 'png'.");
if (Quality is { } q && (q < 1 || q > 100))
throw new ArgumentException("Quality must be between 1 and 100.");
if (MaxWidth is { } w && w <= 0) throw new ArgumentException("MaxWidth must be positive.");
if (MaxHeight is { } h && h <= 0) throw new ArgumentException("MaxHeight must be positive.");
}
}
/Services/ImageCompressionService.cs
using Aspose.Imaging;
using Aspose.Imaging.ImageOptions;
using ImageApi.Models;
namespace ImageApi.Services;
public interface IImageCompressionService
{
Task<(MemoryStream output, string contentType, string fileExt)> CompressAsync(
Stream input, CompressionRequest req, CancellationToken ct = default);
}
public sealed class ImageCompressionService : IImageCompressionService
{
private readonly ILogger<ImageCompressionService> _logger;
public ImageCompressionService(ILogger<ImageCompressionService> logger)
{
_logger = logger;
}
public async Task<(MemoryStream output, string contentType, string fileExt)> CompressAsync(
Stream input, CompressionRequest req, CancellationToken ct = default)
{
req.Validate();
// Defensive copy to a seekable stream
var inbound = new MemoryStream();
await input.CopyToAsync(inbound, ct).ConfigureAwait(false);
inbound.Position = 0;
// Load image via Aspose.Imaging
using var image = Image.Load(inbound);
// Optional: strip metadata (where applicable)
if (req.StripMetadata)
{
TryStripMetadata(image);
}
// Optional resize (preserve aspect ratio)
if (req.MaxWidth.HasValue || req.MaxHeight.HasValue)
{
ResizeInPlace(image, req.MaxWidth, req.MaxHeight);
}
// Choose encoder and options
string fmt = req.Format.ToLowerInvariant();
var (options, contentType, ext) = BuildOptions(fmt, req.Quality);
// Save to output
var output = new MemoryStream();
image.Save(output, options);
output.Position = 0;
_logger.LogInformation("Compressed image to {Bytes} bytes as {Ext}", output.Length, ext);
return (output, contentType, ext);
}
private static void ResizeInPlace(Image image, int? maxW, int? maxH)
{
var w = image.Width;
var h = image.Height;
double scaleW = maxW.HasValue ? (double)maxW.Value / w : 1.0;
double scaleH = maxH.HasValue ? (double)maxH.Value / h : 1.0;
double scale = Math.Min(scaleW, scaleH);
if (scale < 1.0)
{
int newW = Math.Max(1, (int)Math.Round(w * scale));
int newH = Math.Max(1, (int)Math.Round(h * scale));
image.Resize(newW, newH);
}
}
private static (ImageOptionsBase options, string contentType, string ext) BuildOptions(string fmt, int? quality)
{
switch (fmt)
{
case "jpeg":
{
var q = quality ?? 80;
var jpeg = new JpegOptions { Quality = q };
return (jpeg, "image/jpeg", "jpg");
}
case "png":
{
// PNG is lossless; using defaults ensures broad compatibility.
// Many PNG tunables exist, but defaults are safe and effective.
var png = new PngOptions();
return (png, "image/png", "png");
}
default:
throw new ArgumentOutOfRangeException(nameof(fmt), "Unsupported format.");
}
}
private static void TryStripMetadata(Image image)
{
try
{
// Not every format exposes EXIF/IPTC the same way; a best-effort clear:
if (image is RasterImage raster)
{
raster.RemoveAllFonts();
raster.SetPropertyItems(Array.Empty<PropertyItem>());
}
}
catch
{
// Non-fatal; ignore if format doesn't support these operations
}
}
}
Notes
JpegOptions.Quality
۱ تا ۱۰۰) کنترل ضعف را کنترل می کند.- پیش فرض های PNG معمولا برای یک نسخه اول خوب است؛ اگر شما نیاز به پینگ های کوچک اضافی، شما می توانید اضافه کردن پیشرفته بعد از آن.
TryStripMetadata
این یک رویکرد با بهترین تلاش است؛ APIs متا داده ها با توجه به فرمت منبع متفاوت است.
/Controllers/ImageController.cs
using ImageApi.Models;
using ImageApi.Services;
using Microsoft.AspNetCore.Mvc;
namespace ImageApi.Controllers;
[ApiController]
[Route("api/images")]
public sealed class ImageController : ControllerBase
{
private static readonly HashSet<string> AllowedContentTypes = new(StringComparer.OrdinalIgnoreCase)
{
"image/jpeg", "image/png", "image/gif", "image/webp", "image/bmp", "image/tiff"
};
private readonly IImageCompressionService _svc;
private readonly ILogger<ImageController> _logger;
public ImageController(IImageCompressionService svc, ILogger<ImageController> logger)
{
_svc = svc;
_logger = logger;
}
// POST /api/images/compress?format=jpeg&quality=75&maxWidth=1280&maxHeight=1280
[HttpPost("compress")]
[RequestSizeLimit(25_000_000)] // 25 MB cap; adjust to your needs
public async Task<IActionResult> Compress(
[FromQuery] string? format,
[FromQuery] int? quality,
[FromQuery] int? maxWidth,
[FromQuery] int? maxHeight,
[FromQuery] bool stripMetadata = true,
IFormFile? file = null,
CancellationToken ct = default)
{
if (file is null || file.Length == 0)
return BadRequest("No file uploaded.");
if (!AllowedContentTypes.Contains(file.ContentType))
return BadRequest("Unsupported content type. Upload a common raster image (JPEG, PNG, GIF, WebP, BMP, TIFF).");
var req = new CompressionRequest
{
Format = string.IsNullOrWhiteSpace(format) ? "jpeg" : format!,
Quality = quality,
MaxWidth = maxWidth,
MaxHeight = maxHeight,
StripMetadata = stripMetadata
};
await using var input = file.OpenReadStream();
var (output, contentType, ext) = await _svc.CompressAsync(input, req, ct);
// Strong caching for immutable responses (tune for your app/CDN)
Response.Headers.CacheControl = "public,max-age=31536000,immutable";
return File(output, contentType, fileDownloadName: BuildDownloadName(file.FileName, ext));
}
private static string BuildDownloadName(string originalName, string newExt)
{
var baseName = Path.GetFileNameWithoutExtension(originalName);
return $"{baseName}-compressed.{newExt}";
}
}
Program.cs
(آموزش + مجوز اختیاری)
using Aspose.Imaging;
using ImageApi.Services;
var builder = WebApplication.CreateBuilder(args);
// Optional: initialize Aspose license from a file or stream if you have one
// var license = new Aspose.Imaging.License();
// license.SetLicense("Aspose.Total.lic");
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddSingleton<IImageCompressionService, ImageCompressionService>();
var app = builder.Build();
app.UseRouting();
app.UseAuthorization();
app.MapControllers();
// Enable for local testing
app.UseSwagger();
app.UseSwaggerUI();
app.Run();
راهنمای گام به گام
مرحله اول: طرح را تنظیم کنید
ایجاد یک پروژه ASP.NET Core Web API. Aspose.Imaging
بایگانی برچسب ها: ایجاد Models
, Services
, و Controllers
پوشه ها همانطور که در بالا نشان داده شده است.
مرحله 2: تنظیم Aspose.Imaging (تولید مجوز اختیاری)
اگر شما یک مجوز دارید، آن را در استارتاپ شروع کنید (نگاه کنید به Program.cs
این امر مانع از ارزیابی شاخص های آب می شود و عملکرد کامل را تضمین می کند.
مرحله سوم: استفاده از سرویس فشرده سازی
در این ImageCompressionService
:
- تصاویری از طریق
Image.Load(Stream)
- به صورت اختیاری متابولیسم را انتخاب کنید
- به صورت اختیاری با نسبت ظاهر حفظ می شود.
- صرفه جویی در JPEG یا PNG با گزینه های مناسب برای فرمت
مرحله 4: ایجاد کنترلر API
ImageController
نمایشگاه ها POST /api/images/compress
یک فایل و پارامترهای پرسشنامه:
format
:jpeg
یاpng
(به صورت پیش فرضjpeg
)quality
: 1 تا 100 (فقط JPEG؛ پیش فرض 80)maxWidth
/maxHeight
: محدودیت ها برای کاهشstripMetadata
فایرفاکسtrue
برای تولید کمتری
مرحله پنجم: آزمایش آتش سوزی
استفاده از هر مشتری HTTP برای ارسال یک multipart/form-data
درخواست با یک فیلد فایل نامیده می شود file
، به علاوه پارامترهای پرس و جو اختیاری را بررسی کنید:
- Response
Content-Type
بازی فرمت - حجم فایل بازگردانده شده کاهش می یابد
- بازگرداندن کارهای پیش بینی شده
انتخاب طراحی و بهترین شیوه ها
- ** تنظیمات آگاهی از فرمت**: استفاده از JPEG
Quality
PNG برای تولید قابل پیش بینی بدون زیان باقی می ماند. - Downscale قبل از رمزگذاری: بازگرداندن اولین پیکسل ها را کاهش می دهد (بزرگترین اندازه ها برنده می شوند) و سپس بایت های کوتاه را به کار می گیرد.
- نمایش ورودی ها: نوع محتوای ذخیره، اندازه فایل، محدودیت های پرس و جو.
- ترافیک: اجتناب از خواندن کل فایل به حافظه تکرار؛ نگه داشتن جریان کوتاه مدت و قابل جستجو.
- Caching: اگر نام/محتویات را از ورودی های تعیین کننده به دست آورید، پاسخ های رمزگذاری ناپایدار را نشان می دهد؛ در غیر این صورت عنوان های ذخیره سازی را به مورد استفاده خود اضافه کنید.
- امنیت: نوع محتوا را تأیید کنید و بار پرداخت مشکوک را رد کنید.در نظر گرفتن اسکن برای تصاویر نادرست.
- ** قابل مشاهده**: اندازه های قبل و بعد از ثبت نام و پارامترهای مورد استفاده؛ این به شما کمک می کند تا تنظیمات پیش فرض را انجام دهید.
- تلاش: در صورت قرار گرفتن در معرض عموم، محدودیت نرخ و یا نیاز به auth برای جلوگیری از سوءاستفاده.
گسترش های معمولی (بعد از آن)
- WebP/AVIF رمزگذاری برای تصاویر حتی کوچکتر (به گزینه های جدید اضافه کنید/
contentType
/تمدید فایل درBuildOptions
). - PNG tuning (درجه فیلتر / فشرده سازی) اگر شما نیاز به دارایی های کوچک اضافی بدون از دست دادن.
- تصویب پروفایل ها مانند
thumbnail
,preview
,hires
از پارامترهای شناخته شده استفاده کنید. - ETags یا hashing محتوا برای پاسخ های یکسان از cache.
- Async batch endpoint برای فشرده سازی چندین فایل به طور همزمان.
Troubleshooting
- تولیدات بزرگ: افزایش
RequestSizeLimit
یا جریان به temp ذخیره سازی. - ** رنگ های روشن**: اطمینان از فضای رنگی با تنظیمات پیش فرض پردازش می شود؛ موارد پیشرفته ممکن است نیاز به نوع رنگ صریح داشته باشد.
- بدون کاهش اندازه (PNG): PNG بدون از دست دادن است؛ امکان بازگشت یا تغییر به JPEG برای صرفه جویی در بایت قوی تر است.
خلاصه
شما در حال حاضر یک اپلیکیشن فشرده سازی تصویر پویا آماده تولید با استفاده از Aspose.Imaging. کنترلر مدیریت بارگذاری ها و پارامترها؛ سرویس اعمال می شود امن، فرمت-آگاهی و بازگرداندن اختیاری، پس از آن جریان بازگشت یک پاسخ به درستی تایپ شده با عنوان های مخفی. از اینجا، شما می توانید اضافه کردن بیشتر قالب ها، پیش تنظیمات، و استراتژی های خفیف برای مطابقت با صفحه وب خود را.
More in this category
- بهینه سازی GIF های متحرک در .NET با استفاده از Aspose.Imaging
- بهینه سازی TIFF های چند صفحه ای برای آرشیو در .NET با Aspose
- HEIC به JPEG/PNG تبدیل با Aspose.Imaging برای .NET
- استخراج تصاویر محصول برای پلتفرم های تجارت الکترونیک با استفاده از Aspose.Imaging برای .NET
- انیمیشن های مبتنی بر داده در .NET با Aspose.Imaging