BackgroundBuilder/Services/ImageService.cs
Giuliano Paschoalino 47ac74d87b Nova funcionalidade e ajustes em processamento de dados
Adicionada funcionalidade para salvar imagem em caminho de rede
compartilhado no `ImageService.cs`. No `MainWindowViewModel.cs`,
incluída mensagem de confirmação e abertura automática da imagem
gerada. Ajustada lógica de mapeamento de colunas no processamento
de planilhas, com mudanças nas correspondências e início da
segunda tabela. Adicionada verificação para evitar erros ao buscar
aniversários. Mensagem de confirmação adicionada ao final do
processamento da planilha.
2025-08-28 14:52:47 -03:00

186 lines
7.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace BackgroundBuilder.Services
{
public class ImageService : IImageService
{
// no longer injected — use a private constant
private static readonly Thickness OverlayOffset = new(10, 53, 10, 53);
public async Task<BitmapImage> LoadAsync(string path)
{
// Load image from disk into BitmapImage
var bmp = new BitmapImage();
using var stream = File.OpenRead(path);
bmp.BeginInit();
bmp.UriSource = new Uri(path, UriKind.Absolute);
bmp.CacheOption = BitmapCacheOption.OnLoad;
bmp.EndInit();
// no real async work—return completed task
return await Task.FromResult(bmp);
}
public async Task SaveAsync(
FrameworkElement overlay,
BitmapImage background,
string primaryPath,
string? overlayPath = null)
{
string? savedOverlayPath = null;
if (!string.IsNullOrWhiteSpace(overlayPath))
{
var overlayBmp = RenderComposite(overlay, null, new Thickness(0));
SaveBitmap(overlayBmp, overlayPath!);
savedOverlayPath = overlayPath;
}
var compositeBmp = RenderComposite(overlay, background, OverlayOffset);
SaveBitmap(compositeBmp, primaryPath);
SaveBitmap(compositeBmp, "\\\\SRV-DADOS\\Wallpaper$\\Wallpaper.png");
await Task.FromResult((primaryPath, savedOverlayPath));
}
/// <summary>
/// Renders a <paramref name="background"/> plus the <paramref name="mainGrid"/>
/// at bottomright offset by <paramref name="offset"/>. If background is null,
/// only the mainGrid is rendered at (0,0).
/// </summary>
private static RenderTargetBitmap RenderComposite(
FrameworkElement mainGrid,
BitmapImage? background,
Thickness offset,
int taskbarHeight = 0)
{
double width = background?.PixelWidth ?? mainGrid.ActualWidth;
double height = background?.PixelHeight ?? mainGrid.ActualHeight;
// Measure & arrange the mainGrid so ActualWidth/Height are valid
mainGrid.Measure(new Size(width, height));
mainGrid.Arrange(new Rect(0, 0, mainGrid.DesiredSize.Width, mainGrid.DesiredSize.Height));
double gridWidth = mainGrid.ActualWidth > 0 ? mainGrid.ActualWidth : mainGrid.DesiredSize.Width;
double gridHeight = mainGrid.ActualHeight > 0 ? mainGrid.ActualHeight : mainGrid.DesiredSize.Height;
double x;
double y;
double scale;
if (background != null)
{
// Calculate max allowed size (half background, minus taskbar for height)
double maxWidth = width;
double maxHeight = (height - taskbarHeight);
// Compute scale factor to fit within maxWidth/maxHeight, preserving aspect ratio
scale = Math.Min(1.0, Math.Min(maxWidth / gridWidth, maxHeight / gridHeight));
double scaledWidth = gridWidth * scale;
double scaledHeight = gridHeight * scale;
// Place at lower right, offset
x = width - scaledWidth - offset.Right;
y = height - scaledHeight - offset.Bottom;
gridWidth = scaledWidth;
gridHeight = scaledHeight;
}
else
{
// When rendering without background, use the mainGrid's own size and render at (0,0)
// --- Fix: Ensure full layout and hide scrollbars before rendering ---
mainGrid.UpdateLayout();
// If mainGrid is a ScrollViewer or contains one, hide scrollbars
if (mainGrid is System.Windows.Controls.ScrollViewer sv)
{
sv.HorizontalScrollBarVisibility = System.Windows.Controls.ScrollBarVisibility.Hidden;
sv.VerticalScrollBarVisibility = System.Windows.Controls.ScrollBarVisibility.Hidden;
}
// If mainGrid contains a DataGrid or similar, try to hide scrollbars
if (mainGrid is System.Windows.Controls.Panel panel)
{
foreach (var child in panel.Children)
{
if (child is System.Windows.Controls.DataGrid dg)
{
dg.HorizontalScrollBarVisibility = System.Windows.Controls.ScrollBarVisibility.Hidden;
dg.VerticalScrollBarVisibility = System.Windows.Controls.ScrollBarVisibility.Hidden;
}
}
}
// Re-measure after hiding scrollbars
mainGrid.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
mainGrid.Arrange(new Rect(0, 0, mainGrid.DesiredSize.Width, mainGrid.DesiredSize.Height));
mainGrid.UpdateLayout();
gridWidth = mainGrid.ActualWidth > 0 ? mainGrid.ActualWidth : mainGrid.DesiredSize.Width;
gridHeight = mainGrid.ActualHeight > 0 ? mainGrid.ActualHeight : mainGrid.DesiredSize.Height;
width = (int)Math.Ceiling(gridWidth);
height = (int)Math.Ceiling(gridHeight);
x = 0;
y = 0;
}
var dv = new DrawingVisual();
using (var ctx = dv.RenderOpen())
{
// Draw background if provided
if (background != null)
{
ctx.DrawImage(background, new Rect(0, 0, width, height));
}
// Draw mainGrid at calculated position, with scaling if needed
var brush = new VisualBrush(mainGrid)
{
Stretch = Stretch.Uniform,
};
ctx.DrawRectangle(brush, null, new Rect(x, y, gridWidth, gridHeight));
}
var rtb = new RenderTargetBitmap(
(int)width,
(int)height,
96,
96,
PixelFormats.Pbgra32);
rtb.Render(dv);
return rtb;
}
/// <summary>
/// Encodes the given bitmap as PNG and writes it to disk.
/// </summary>
private static void SaveBitmap(RenderTargetBitmap bitmap, string path)
{
try
{
var directory = Path.GetDirectoryName(path);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory!);
}
using var fs = new FileStream(path, FileMode.Create, FileAccess.Write);
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmap));
encoder.Save(fs);
}
catch (Exception ex)
{
MessageBox.Show($"Erro ao salvar a imagem:\n{ex.Message}\n\nCaminho: {path}");
}
}
}
}