feat: 初始功能
This commit is contained in:
88
Services/Printing/ImagePrintJobExecutor.cs
Normal file
88
Services/Printing/ImagePrintJobExecutor.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using CloudPrint.Client.Models;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Printing;
|
||||
using System.IO;
|
||||
|
||||
namespace CloudPrint.Client.Services.Printing;
|
||||
|
||||
public sealed class ImagePrintJobExecutor : IPrintJobExecutor
|
||||
{
|
||||
private readonly IWindowsPrintQueueService _queueService;
|
||||
|
||||
private static readonly HashSet<string> SupportedExtensions = new(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
".jpg", ".jpeg", ".png", ".bmp", ".gif"
|
||||
};
|
||||
|
||||
public ImagePrintJobExecutor(IWindowsPrintQueueService queueService)
|
||||
{
|
||||
_queueService = queueService;
|
||||
}
|
||||
|
||||
public bool CanHandle(PrintJob job)
|
||||
{
|
||||
return SupportedExtensions.Contains(Path.GetExtension(job.FilePath));
|
||||
}
|
||||
|
||||
public Task ExecuteAsync(PrintJob job, IProgress<int>? progress, CancellationToken cancellationToken = default)
|
||||
{
|
||||
PrintFileGuards.EnsurePrintableFile(job);
|
||||
|
||||
return Task.Run(() =>
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
using var image = Image.FromFile(job.FilePath);
|
||||
using var document = new PrintDocument
|
||||
{
|
||||
DocumentName = string.IsNullOrWhiteSpace(job.FileName) ? job.JobNo : job.FileName,
|
||||
PrinterSettings =
|
||||
{
|
||||
PrinterName = job.PrinterName,
|
||||
Copies = (short)Math.Clamp(job.Copies, 1, short.MaxValue)
|
||||
}
|
||||
};
|
||||
|
||||
if (document.PrinterSettings.CanDuplex)
|
||||
{
|
||||
document.PrinterSettings.Duplex = job.Duplex ? Duplex.Vertical : Duplex.Simplex;
|
||||
}
|
||||
|
||||
document.DefaultPageSettings.Color = job.Color;
|
||||
document.PrintPage += (_, args) => DrawImageToPage(image, args);
|
||||
progress?.Report(20);
|
||||
document.Print();
|
||||
CaptureWindowsJob(job, document.DocumentName);
|
||||
progress?.Report(100);
|
||||
}, cancellationToken);
|
||||
}
|
||||
|
||||
private void CaptureWindowsJob(PrintJob job, string documentName)
|
||||
{
|
||||
var queueJob = _queueService.FindLatestJob(job.PrinterName, documentName);
|
||||
if (queueJob is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
job.WindowsJobId = queueJob.JobId;
|
||||
job.WindowsJobStatus = queueJob.Status;
|
||||
}
|
||||
|
||||
private static void DrawImageToPage(Image image, PrintPageEventArgs args)
|
||||
{
|
||||
if (args.Graphics is null)
|
||||
{
|
||||
throw new InvalidOperationException("打印图形上下文不可用");
|
||||
}
|
||||
|
||||
var bounds = args.MarginBounds;
|
||||
var ratio = Math.Min(bounds.Width / (double)image.Width, bounds.Height / (double)image.Height);
|
||||
var width = (int)(image.Width * ratio);
|
||||
var height = (int)(image.Height * ratio);
|
||||
var x = bounds.Left + (bounds.Width - width) / 2;
|
||||
var y = bounds.Top + (bounds.Height - height) / 2;
|
||||
|
||||
args.Graphics.DrawImage(image, x, y, width, height);
|
||||
args.HasMorePages = false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user