From 14312cb5c6f3f21742750e501adf0bb48522b1d7 Mon Sep 17 00:00:00 2001 From: Sergey Chebotar Date: Mon, 5 Jun 2023 07:01:44 +0300 Subject: [PATCH] Add thumbnail file creation --- Controllers/ProductsController.cs | 228 ++++++++++++++++-------------- MyDarling.csproj | 1 + Program.cs | 3 + Services/IImageResizer.cs | 8 ++ Services/ImageResizer.cs | 43 ++++++ 5 files changed, 174 insertions(+), 109 deletions(-) create mode 100644 Services/IImageResizer.cs create mode 100644 Services/ImageResizer.cs diff --git a/Controllers/ProductsController.cs b/Controllers/ProductsController.cs index 14a4b27..79b4efd 100644 --- a/Controllers/ProductsController.cs +++ b/Controllers/ProductsController.cs @@ -3,131 +3,141 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using MyDarling.Models; +using MyDarling.Services; namespace MyDarling.Controllers { - [Authorize] - public class ProductsController : Controller - { - private DataContext context; - private IWebHostEnvironment environment; + [Authorize] + public class ProductsController : Controller + { + private DataContext context; + private IWebHostEnvironment environment; + private IImageResizer resizer; - public ProductsController(DataContext context, IWebHostEnvironment environment) - { - this.environment = environment; - this.context = context; - } + public ProductsController(DataContext context, IImageResizer resizer, IWebHostEnvironment environment) + { + this.environment = environment; + this.context = context; + this.resizer = resizer; + } - public IActionResult Index() - { - return View(context.Products.Include(b => b.Figures)); - } + public IActionResult Index() + { + return View(context.Products.Include(b => b.Figures)); + } - public IActionResult Create() - { - return View(); - } + public IActionResult Create() + { + return View(); + } - [HttpPost] - public async Task Create([Bind] Product bundle) - { - try - { - if (ModelState.IsValid) - { - await context.Products.AddAsync(bundle); - context.SaveChanges(); - return RedirectToAction(nameof(Index)); - } - } - catch (DataException) - { - ModelState.AddModelError("", "Unable to save changes"); - } - return View(bundle); - } + [HttpPost] + public async Task Create([Bind] Product bundle) + { + try + { + if (ModelState.IsValid) + { + await context.Products.AddAsync(bundle); + context.SaveChanges(); + return RedirectToAction(nameof(Index)); + } + } + catch (DataException) + { + ModelState.AddModelError("", "Unable to save changes"); + } + return View(bundle); + } - public async Task Details(string id) - { - return View(await context.Products.Include(b => b.Figures).Where(b => b.Id.Equals(id)).FirstOrDefaultAsync()); - } + public async Task Details(string id) + { + return View(await context.Products.Include(b => b.Figures).Where(b => b.Id.Equals(id)).FirstOrDefaultAsync()); + } - [HttpPost] - public async Task Edit(string id) - { - if (string.IsNullOrEmpty(id)) - { - return NotFound(); - } + [HttpPost] + public async Task Edit(string id) + { + if (string.IsNullOrEmpty(id)) + { + return NotFound(); + } - var product = await context.Products.FindAsync(id); - if (product == null) - { - return NotFound(); - } + var product = await context.Products.FindAsync(id); + if (product == null) + { + return NotFound(); + } - var file = Request.Form.Files.FirstOrDefault(); + var file = Request.Form.Files.FirstOrDefault(); + string fullPath = string.Empty; - if (await TryUpdateModelAsync( - product, - "", - b => b.Name, b => b.Description, b => b.Figures, b => b.Price)) - { - if (file != null) - { - var newFigure = new Figure(string.Empty, product.Id); - product.Figures.Add(newFigure); - string filePath = $"/Content/{product.Id}/{newFigure.Id}.jpg"; - var savePath = environment.WebRootPath + "/Content/" + product.Id + "/"; - if (!Directory.Exists(savePath)) - { - Directory.CreateDirectory(savePath); - } - using var fileStream = new FileStream(environment.WebRootPath + filePath, FileMode.Create); - await file.CopyToAsync(fileStream); - } + if (await TryUpdateModelAsync( + product, + "", + b => b.Name, b => b.Description, b => b.Figures, b => b.Price)) + { + if (file != null) + { + var newFigure = new Figure(string.Empty, product.Id); + product.Figures.Add(newFigure); + string filePath = $"/Content/{product.Id}/{newFigure.Id}.jpg"; + string directoryPath = environment.WebRootPath + "/Content/" + product.Id + "/"; + fullPath = environment.WebRootPath + filePath; + if (!Directory.Exists(directoryPath)) + { + Directory.CreateDirectory(directoryPath); + } + using var fileStream = new FileStream(fullPath, FileMode.Create); + await file.CopyToAsync(fileStream); + } + + if (!string.IsNullOrEmpty(fullPath)) + { + resizer.CreateThumbnail(fullPath); + } - try - { - await context.SaveChangesAsync(); + try + { + await context.SaveChangesAsync(); return RedirectToAction("Details", "Products", new { Id = product?.Id}); - } + } - catch (System.Exception) - { - ModelState.AddModelError("", "Unable to save changes"); - } - } - return View(product); - } + catch (System.Exception) + { + ModelState.AddModelError("", "Unable to save changes"); + } + } + return View(product); + } - [HttpPost] - public async Task Delete(string id) - { - var productToDelete = await context.Products.FindAsync(id); - if (productToDelete == null) - { - return NotFound(); - } + [HttpPost] + public async Task Delete(string id) + { + var productToDelete = await context.Products.FindAsync(id); + if (productToDelete == null) + { + return NotFound(); + } - try - { - var bundleDirPath = String.Concat(environment.WebRootPath, - "/Content/", - productToDelete.Id); + try + { + var bundleDirPath = String.Concat(environment.WebRootPath, + "/Content/", + productToDelete.Id); - if (Directory.Exists(bundleDirPath)) - { - Directory.Delete(bundleDirPath, true); - } - context.Products.Remove(productToDelete); - await context.SaveChangesAsync(); - return RedirectToAction(nameof(Index)); - } - catch (DbUpdateException) - { - return RedirectToAction(nameof(Delete), new { id = id, saveChangesError = true }); - } - } - } + if (Directory.Exists(bundleDirPath)) + { + Directory.Delete(bundleDirPath, true); + } + context.Products.Remove(productToDelete); + await context.SaveChangesAsync(); + return RedirectToAction(nameof(Index)); + } + catch (DbUpdateException) + { + return RedirectToAction(nameof(Delete), new { id = id, saveChangesError = true }); + } + } + } } \ No newline at end of file diff --git a/MyDarling.csproj b/MyDarling.csproj index 7ed30cd..300fb2e 100644 --- a/MyDarling.csproj +++ b/MyDarling.csproj @@ -13,6 +13,7 @@ all + diff --git a/Program.cs b/Program.cs index 361be3e..d3db670 100644 --- a/Program.cs +++ b/Program.cs @@ -1,7 +1,9 @@ using Microsoft.EntityFrameworkCore; using MyDarling.Models; +using MyDarling.Services; using Microsoft.AspNetCore.Identity; + var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext(opts => @@ -25,6 +27,7 @@ builder.Services.Configure( opts => opts.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyz"; }); +builder.Services.AddTransient(); builder.Services.AddControllersWithViews(); builder.Services.AddRazorPages(); diff --git a/Services/IImageResizer.cs b/Services/IImageResizer.cs new file mode 100644 index 0000000..de02893 --- /dev/null +++ b/Services/IImageResizer.cs @@ -0,0 +1,8 @@ +namespace MyDarling.Services +{ + public interface IImageResizer + { + public void CreateThumbnail(string filePath); + public void DownsizeImage(string filePath); + } +} \ No newline at end of file diff --git a/Services/ImageResizer.cs b/Services/ImageResizer.cs new file mode 100644 index 0000000..53c1eec --- /dev/null +++ b/Services/ImageResizer.cs @@ -0,0 +1,43 @@ +using SkiaSharp; + +namespace MyDarling.Services +{ + public class ImageResizer : IImageResizer + { + const int size = 400; + const int quality = 75; + public void CreateThumbnail(string inputPath) + { + using var input = File.OpenRead(inputPath); + using var inputStream = new SKManagedStream(input); + using var original = SKBitmap.Decode(inputStream); + + int width, height; + if (original.Width > original.Height) + { + width = size; + height = original.Height * size / original.Width; + } + else + { + width = original.Width * size / original.Height; + height = size; + } + + using var resized = original.Resize(new SKImageInfo(width, height), SKFilterQuality.High); + if (resized == null) return; + + using var image = SKImage.FromBitmap(resized); + var outputPath = Path.GetDirectoryName(inputPath) + "\\" + + Path.GetFileNameWithoutExtension(inputPath) + "_thumb.jpg"; + using var output = File.OpenWrite(outputPath); + + image.Encode(SKEncodedImageFormat.Jpeg, quality).SaveTo(output); + } + + public void DownsizeImage(string filePath) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file