ในยุคดิจิตอลของวันนี้การจัดการภาพที่มีประสิทธิภาพเป็นสิ่งสําคัญสําหรับแอปพลิเคชันเว็บและ APIs หนึ่งในด้านหลักของการจัดการรูปภาพคือการบีบอัดซึ่งช่วยในการลดขนาดไฟล์โดยไม่ส่งผลกระทบอย่างมีนัยสําคัญต่อคุณภาพ คู่มือนี้จะช่วยให้คุณผ่านการสร้าง API แอมป์ภาพแบบไดนามิกโดยใช้ Aspose.Imaging สําหรับ .NET ในที่สุดคุณจะมี API Web Core ASP.NET ที่ใช้งานได้ซึ่งยอมรับภาพและส่งคืนผลผลิตที่แอมเพรสตามพารามิเตอร์คําถาม (รูปแบบคุณภาพการรีไซเคิลและอื่น ๆ )
Aspose.Imaging เป็นห้องสมุดที่มีประสิทธิภาพสําหรับการทํางานกับภาพใน .NET มันสนับสนุนรูปแบบหลายรูปแบบและให้คุณสมบัติการจัดการที่แข็งแกร่งรวมถึงการสูญเสีย (JPEG) และการทํางานที่ไม่มีการเสียหาย (PNG) เราจะใช้มันเพื่อสร้างบริการการบีบอัดที่มีประสิทธิภาพและสามารถปรับขนาดได้
สิ่งที่คุณจะสร้าง
- *จุดสิ้นสุด *:
POST /api/images/compress?format=jpeg&quality=75&maxWidth=1280&maxHeight=1280
- อินพุต: ไฟล์หลายส่วน (ภาพ) พารามิเตอร์การสอบถามตัวเลือกสําหรับรูปแบบ / คุณภาพ / ขนาด
- ** Outputs**: กระแสภาพที่บีบอัดพร้อมกับที่ถูกต้อง
Content-Type
และหัว caching - ความปลอดภัย: การยืนยันประเภทเนื้อหาข้อ จํากัด ขนาดและ decode / encode ที่เก็บไว้
ข้อกําหนด
- .NET 8 (หรือ .Net 6 +)
- ASP.NET Core Web API โครงการ
- หมายเลข:
Aspose.Imaging
- ตัวเลือก: การเปิดตัวใบอนุญาตในแอปพลิเคชันเริ่มต้น (ถ้าคุณใช้โครงสร้างที่ได้รับอนุญาโตตุลาการ)
โครงสร้างโครงการ (ขั้นต่ํา)
/Controllers
ImageController.cs
/Services
ImageCompressionService.cs
/Models
CompressionRequest.cs
Program.cs
appsettings.json
ตัวอย่างเต็มรูปแบบ (เซิร์ฟเวอร์ + ผู้ควบคุม)
เปลี่ยนพื้นที่ชื่อผู้ประกอบการด้วยพื้นที่ ชื่อของโครงการของคุณ
/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
(1-100) ควบคุมการบีบอัดความเสียหาย- ข้อกําหนดของ PNG โดยปกติจะดีสําหรับรุ่นแรก หากคุณต้องการ P NG ขนาดเล็กพิเศษคุณสามารถเพิ่มการปรับปรุงขั้นสูงในภายหลัง
TryStripMetadata
เป็นวิธีการที่ดีที่สุดที่พยายาม; APIs metadata แตกต่างกันตามรูปแบบแหล่งข้อมูล
/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
(DI การลงทะเบียน + ใบอนุญาตทางเลือก)
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();
คู่มือขั้นตอน
ขั้นตอนที่ 1: สร้างโครงการ
สร้างโครงการ ASP.NET Core Web API ที่เพิ่ม Aspose.Imaging
NuGet แพคเกจ สร้าง Models
, Services
, และ Controllers
โพสต์ตามที่แสดงไว้ข้างต้น
ขั้นตอน 2: การตั้งค่า Aspose.Imaging (ใบอนุญาตทางเลือก)
หากคุณมีใบอนุญาตให้เริ่มต้นที่ startup (ดู Program.cs
). นี้หลีกเลี่ยงการประเมินเครื่องหมายน้ําและให้แน่ใจว่าการทํางานอย่างสมบูรณ์
ขั้นตอนที่ 3: การดําเนินการบริการการบีบอัด
อะไร ImageCompressionService
:
- ดาวน์โหลดภาพผ่าน
Image.Load(Stream)
- ตัวเลือก strips metadata
- ตัวเลือกการรีไซเคิลด้วยความสัมพันธ์ด้านที่เก็บรักษา
- การประหยัด JPEG หรือ PNG ด้วยตัวเลือกที่เหมาะสมกับรูปแบบ
ขั้นตอน 4: สร้างตัวควบคุม API
ImageController
แสดง POST /api/images/compress
ใช้ไฟล์และคําถามพารามิเตอร์:
format
:jpeg
หรือpng
(การกําหนดค่าjpeg
)quality
: 1-100 (JPEG เท่านั้น; default 80)maxWidth
/maxHeight
: ข้อ จํากัด สําหรับการลดลงstripMetadata
หมายเลขรุ่น: defaulttrue
สําหรับการผลิตขนาดเล็ก
ขั้นตอน 5: การทดสอบ API
ใช้ลูกค้า HTTP ใด ๆ เพื่อส่ง multipart/form-data
คําขอที่มีฟิลด์ไฟล์เดียวที่เรียกว่า file
, plus ตัวเลือกคําถามพารามิเตอร์ ตรวจสอบ:
- Response
Content-Type
รูปแบบการแข่งขัน - ขนาดไฟล์ที่กลับมาจะลดลง
- การดําเนินการตามที่คาดหวัง
การเลือกการออกแบบและการปฏิบัติที่ดีที่สุด
- การตั้งค่าข้อมูลแบบฟอร์ม: JPEG ใช้
Quality
; PNG ยังคงไม่มีการสูญเสียสําหรับการผลิตที่คาดการณ์ได้ - Downscale ก่อนที่เข้ารหัส: การรีไซเคิลลดพิกเซลครั้งแรก (ขนาดใหญ่ที่สุดชนะ) จากนั้นรหัสสกรูบิตเพิ่มเติม
- การทําความสะอาดป้อนข้อมูล: ประเภทเนื้อหาบันทึกขนาดไฟล์ขอบเขตการสอบถาม
- ** Streaming**: หลีกเลี่ยงการอ่านไฟล์ทั้งหมดลงในหน่วยความจําอย่างต่อเนื่อง ช่วยให้การไหลเป็นระยะสั้นและสามารถค้นหาได้
- Caching: คํานวณการตอบสนองเป็นไม่เปลี่ยนแปลงถ้าคุณได้รับชื่อ / เนื้อหาจากป้อนข้อมูลที่กําหนดเอง; ในทางอื่น ๆ ปลั๊กหัว cache ไปยังกรณีการใช้ของคุณ
- ความปลอดภัย: ตรวจสอบประเภทเนื้อหาและปฏิเสธค่าธรรมเนียมที่น่าสงสัย โปรดพิจารณาการสแกนสําหรับภาพที่ผิดปกติ
- การสังเกตได้: ขนาดการบันทึกก่อน / หลังจากและพารามิเตอร์ที่ใช้ ซึ่งจะช่วยให้คุณแก้ไขข้อกําหนด
- การหลอกลวง: หากถูกเปิดเผยโดยสาธารณะอัตรา จํากัด หรือต้องการ auth เพื่อป้องกันการละเมิด
ความยืดหยุ่นทั่วไป ( drop-in later)
- การเข้ารหัส WebP/AVIF สําหรับภาพขนาดเล็ก (เพิ่มตัวเลือกใหม่/
contentType
/ไฟล์ขยายในBuildOptions
). - PNG tuning (ระดับกรอง / การบีบอัด) ถ้าคุณต้องการสินทรัพย์ที่ไม่เสียหายขนาดเล็กพิเศษ
- การตั้งค่าโปรไฟล์ เช่น
thumbnail
,preview
,hires
แผนที่ไปยังพารามิเตอร์ที่รู้จัก - ** ETags** หรือเนื้อหา hashing เพื่อให้บริการตอบสนองที่คล้ายกันจาก cache
- Async batch endpoint เพื่อบีบอัดไฟล์หลายไฟล์ในเวลาเดียวกัน
Troubleshooting
- อินพุตขนาดใหญ่: เพิ่มขึ้น
RequestSizeLimit
หรือ Stream ไปยัง temp การจัดเก็บ - สีส้ม: พื้นที่สีที่มั่นใจจะได้รับการจัดการโดย default; กรณีขั้นสูงอาจต้องการประเภทสีอย่างชัดเจน
- ไม่มีการลดขนาด (PNG): PNG ไม่ได้สูญเสีย อนุญาตให้รีไซเคิลหรือเปลี่ยนเป็น JPEG สําหรับการประหยัดไบต์ที่แข็งแกร่งมากขึ้น
คําอธิบาย
ตอนนี้คุณมี API การบีบอัดภาพแบบไดนามิกพร้อมการผลิตโดยใช้ Aspose.Imaging ตัวควบคุมจัดการอัปโหลดและพารามิเตอร์ บริการใช้ความปลอดภัยคอมเพรสเซอร์แบบฟอร์มและรีไซเคิลทางเลือกจากนั้นส่งกลับการตอบสนองที่กําหนดเองด้วยหัว cache จากที่นี่คุณสามารถเพิ่มรูปแบบเพิ่มเติมการตั้งค่าและกลยุทธ์ caching เพื่อให้เหมาะกับ stack ของเว็บของคุณ
More in this category
- การเพิ่มประสิทธิภาพของ GIF ของ animated ใน .NET โดยใช้ Aspose.Imaging
- Optimize Multi-Page TIFFs for Archival in .NET ด้วย Aspose
- HEIC ไปยัง JPEG / PNG แปลงด้วย Aspose.Imaging สําหรับ .NET
- การเคลื่อนไหวที่ขับเคลื่อนข้อมูลใน .NET ด้วย Aspose.Imaging
- การบีบอัดภาพที่มีคุณภาพและไม่มีการสูญเสียใน .NET ด้วย Aspose.Imaging