Convert-it/Areas/ImageConverters/Controllers/JpgToWebpController.cs

261 lines
12 KiB
C#

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Webp;
using SixLabors.ImageSharp.Formats.Jpeg;
namespace Convert_It_Online.Areas.ImageConverters.Controllers
{
[Area("ImageConverters")]
public class JpgToWebpController : Controller
{
private readonly IStringLocalizer<SharedResource> _localizer;
private readonly ILogger<JpgToWebpController> _logger;
public JpgToWebpController(IStringLocalizer<SharedResource> localizer, ILogger<JpgToWebpController> logger)
{
_localizer = localizer;
_logger = logger;
}
private void SetCommonViewBagProperties()
{
ViewBag.HomeLink = _localizer["HomeLink"];
ViewBag.TextMenuTitle = _localizer["TextMenuTitle"];
ViewBag.ImageMenuTitle = _localizer["ImageMenuTitle"];
ViewBag.CaseConverterTitle = _localizer["CaseConverterTitle"];
ViewBag.JpgToWebpTitle = _localizer["JpgToWebpTitle"];
ViewBag.HeicToJpgTitle = _localizer["HeicToJpgTitle"];
ViewBag.DocumentMenuTitle = _localizer["DocumentMenuTitle"];
ViewBag.PdfToTextTitle = _localizer["PdfToTextTitle"];
ViewBag.PdfBarcodeTitle = _localizer["PdfBarcodeTitle"];
ViewBag.FooterText = _localizer["FooterText"];
ViewBag.About = _localizer["About"];
ViewBag.Contact = _localizer["Contact"];
ViewBag.Terms = _localizer["Terms"];
}
private void PrepareIndexView()
{
SetCommonViewBagProperties();
ViewBag.PageTitle = _localizer["JpgWebpConverterPageTitle"];
ViewBag.PageDescription = _localizer["JpgWebpConverterPageDescription"];
ViewBag.JpgToWebpTabTitle = _localizer["JpgToWebpTabTitle"];
ViewBag.WebpToJpgTabTitle = _localizer["WebpToJpgTabTitle"];
ViewBag.JpgFileInputLabel = _localizer["JpgFileInputLabel"];
ViewBag.WebpFileInputLabel = _localizer["WebpFileInputLabel"];
ViewBag.ConvertToWebpButton = _localizer["ConvertToWebpButton"];
ViewBag.ConvertToJpgButton = _localizer["ConvertToJpgButton"];
// FAQ properties
ViewBag.FaqWhatTitle = _localizer["JpgWebpFaqWhatTitle"];
ViewBag.FaqWhatContent = _localizer["JpgWebpFaqWhatContent"];
ViewBag.FaqHowTitle = _localizer["JpgWebpFaqHowTitle"];
ViewBag.FaqHowContent = _localizer["JpgWebpFaqHowContent"];
ViewBag.FaqWhyTitle = _localizer["JpgWebpFaqWhyTitle"];
ViewBag.FaqWhyContent = _localizer["JpgWebpFaqWhyContent"];
ViewBag.FaqSecurityTitle = _localizer["JpgWebpFaqSecurityTitle"];
ViewBag.FaqSecurityContent = _localizer["JpgWebpFaqSecurityContent"];
ViewBag.FaqLimitsTitle = _localizer["JpgWebpFaqLimitsTitle"];
ViewBag.FaqLimitsContent = _localizer["JpgWebpFaqLimitsContent"];
ViewBag.MetaDescription = ViewBag.PageDescription;
}
public IActionResult Index()
{
PrepareIndexView();
return View();
}
[HttpPost]
public async Task<IActionResult> ConvertJpgToWebp(IFormFile jpgFile, bool preview = false)
{
if (jpgFile == null || jpgFile.Length == 0)
{
_logger.LogWarning("[JPG-WEBP-CONVERTER] Tentativa de conversão sem arquivo");
if (preview)
{
return Json(new { success = false, message = _localizer["SelectFileError"].Value });
}
ModelState.AddModelError("jpgFile", _localizer["SelectFileError"]);
PrepareIndexView();
return View("Index");
}
if (jpgFile.ContentType != "image/jpeg" && !jpgFile.FileName.ToLower().EndsWith(".jpg") && !jpgFile.FileName.ToLower().EndsWith(".jpeg"))
{
_logger.LogWarning("[JPG-WEBP-CONVERTER] Arquivo JPG inválido: {ContentType}", jpgFile.ContentType);
if (preview)
{
return Json(new { success = false, message = _localizer["InvalidJpgFileError"].Value });
}
ModelState.AddModelError("jpgFile", _localizer["InvalidJpgFileError"]);
PrepareIndexView();
return View("Index");
}
try
{
_logger.LogInformation("[JPG-WEBP-CONVERTER] Iniciando conversão JPG→WebP: {FileName} ({Size} bytes)",
jpgFile.FileName, jpgFile.Length);
var originalSize = jpgFile.Length;
// Limite para preview: 10MB
const long maxPreviewSize = 10 * 1024 * 1024;
using var jpgStream = jpgFile.OpenReadStream();
using var image = await Image.LoadAsync(jpgStream);
using var memoryStream = new MemoryStream();
await image.SaveAsWebpAsync(memoryStream);
var webpData = memoryStream.ToArray();
var convertedSize = webpData.Length;
var fileName = Path.GetFileNameWithoutExtension(jpgFile.FileName) + ".webp";
_logger.LogInformation("[JPG-WEBP-CONVERTER] Conversão JPG→WebP concluída: {OutputFileName} (Original: {OriginalSize}bytes → Convertido: {ConvertedSize}bytes)",
fileName, originalSize, convertedSize);
// Se é request de preview e o arquivo não é muito grande
if (preview && originalSize <= maxPreviewSize && convertedSize <= maxPreviewSize)
{
var base64 = Convert.ToBase64String(webpData);
var base64DataUrl = $"data:image/webp;base64,{base64}";
return Json(new
{
success = true,
base64 = base64DataUrl,
filename = fileName,
originalSize = originalSize,
convertedSize = convertedSize
});
}
// Download normal
return File(webpData, "image/webp", fileName);
}
catch (UnknownImageFormatException)
{
_logger.LogWarning("[JPG-WEBP-CONVERTER] O arquivo JPG parece ser inválido ou o formato não é suportado.");
if (preview)
{
return Json(new { success = false, message = _localizer["InvalidJpgFileError"].Value });
}
ModelState.AddModelError("jpgFile", _localizer["InvalidJpgFileError"]);
ViewBag.ConversionError = _localizer["InvalidJpgFileError"];
PrepareIndexView();
return View("Index");
}
catch (Exception ex)
{
_logger.LogError(ex, "[JPG-WEBP-CONVERTER] Erro ao converter JPG para WebP: {FileName}", jpgFile.FileName);
if (preview)
{
return Json(new { success = false, message = _localizer["ProcessingError"].Value });
}
ModelState.AddModelError("jpgFile", _localizer["ProcessingError"]);
ViewBag.ConversionError = _localizer["ProcessingError"];
PrepareIndexView();
return View("Index");
}
}
[HttpPost]
public async Task<IActionResult> ConvertWebpToJpg(IFormFile webpFile, bool preview = false)
{
if (webpFile == null || webpFile.Length == 0)
{
_logger.LogWarning("[JPG-WEBP-CONVERTER] Tentativa de conversão WebP→JPG sem arquivo");
if (preview)
{
return Json(new { success = false, message = _localizer["SelectFileError"].Value });
}
ModelState.AddModelError("webpFile", _localizer["SelectFileError"]);
PrepareIndexView();
return View("Index");
}
if (webpFile.ContentType != "image/webp" && !webpFile.FileName.ToLower().EndsWith(".webp"))
{
_logger.LogWarning("[JPG-WEBP-CONVERTER] Arquivo WebP inválido: {ContentType}", webpFile.ContentType);
if (preview)
{
return Json(new { success = false, message = "Arquivo WebP inválido ou formato não suportado." });
}
ModelState.AddModelError("webpFile", "Arquivo WebP inválido ou formato não suportado.");
PrepareIndexView();
return View("Index");
}
try
{
_logger.LogInformation("[JPG-WEBP-CONVERTER] Iniciando conversão WebP→JPG: {FileName} ({Size} bytes)",
webpFile.FileName, webpFile.Length);
var originalSize = webpFile.Length;
// Limite para preview: 10MB
const long maxPreviewSize = 10 * 1024 * 1024;
using var webpStream = webpFile.OpenReadStream();
using var image = await Image.LoadAsync(webpStream);
using var memoryStream = new MemoryStream();
await image.SaveAsJpegAsync(memoryStream);
var jpgData = memoryStream.ToArray();
var convertedSize = jpgData.Length;
var fileName = Path.GetFileNameWithoutExtension(webpFile.FileName) + ".jpg";
_logger.LogInformation("[JPG-WEBP-CONVERTER] Conversão WebP→JPG concluída: {OutputFileName} (Original: {OriginalSize}bytes → Convertido: {ConvertedSize}bytes)",
fileName, originalSize, convertedSize);
// Se é request de preview e o arquivo não é muito grande
if (preview && originalSize <= maxPreviewSize && convertedSize <= maxPreviewSize)
{
var base64 = Convert.ToBase64String(jpgData);
var base64DataUrl = $"data:image/jpeg;base64,{base64}";
return Json(new
{
success = true,
base64 = base64DataUrl,
filename = fileName,
originalSize = originalSize,
convertedSize = convertedSize
});
}
// Download normal
return File(jpgData, "image/jpeg", fileName);
}
catch (UnknownImageFormatException)
{
_logger.LogWarning("[JPG-WEBP-CONVERTER] O arquivo WebP parece ser inválido ou o formato não é suportado.");
if (preview)
{
return Json(new { success = false, message = "Arquivo WebP inválido ou formato não suportado." });
}
ModelState.AddModelError("webpFile", "Arquivo WebP inválido ou formato não suportado.");
ViewBag.ConversionError = "Arquivo WebP inválido ou formato não suportado.";
PrepareIndexView();
return View("Index");
}
catch (Exception ex)
{
_logger.LogError(ex, "[JPG-WEBP-CONVERTER] Erro ao converter WebP para JPG: {FileName}", webpFile.FileName);
if (preview)
{
return Json(new { success = false, message = _localizer["ProcessingError"].Value });
}
ModelState.AddModelError("webpFile", _localizer["ProcessingError"]);
ViewBag.ConversionError = _localizer["ProcessingError"];
PrepareIndexView();
return View("Index");
}
}
}
}