c# - 我可以使用 ScreenshotAsync 方法将屏幕截图保存到内存而不是磁盘吗?
问题描述
我正在使用 PuppeteerSharp 从本地托管的 HTML 模板生成 PDF,并希望 PDF 不可搜索,这意味着 PDF 确实只是 PDF 中的一个大图像。我选择采用这种方法是因为我想让文档更难被篡改。
我已经想出了一种生成纯图像 PDF 的技术。我访问并截取 HTML 页面的屏幕截图,将其存储到磁盘,从浏览器访问所述屏幕截图,最后从该图像生成 PDF。PDF 结果很好,但我想了解是否可以消除将图像存储到磁盘的需要。
下面的代码:
功能码
[FunctionName("pdftest")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req,
ILogger log)
{
log.LogInformation($"Browser path: {appInfo.BrowserExecutablePath}");
ViewPortOptions vprtOpts = new ViewPortOptions()
{
DeviceScaleFactor = 2
};
var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true,
ExecutablePath = appInfo.BrowserExecutablePath,
DefaultViewport = vprtOpts
});
var page = await browser.NewPageAsync();
// access the HTML template
await page.GoToAsync(@"C:\experiment\pdf\index.html");
// where to save the screenshot
var file = @"C:\experiment\pdf\index.png";
// where to save the final PDF
var file2 = @"C:\experiment\pdf\index2.pdf";
PdfOptions opts = new PdfOptions()
{
PrintBackground = true,
Width = "794px",
Height = "1122px",
Scale = 1
};
ScreenshotOptions scrOpts = new ScreenshotOptions()
{
FullPage = true,
};
await page.ScreenshotAsync(file, scrOpts);
await page.GoToAsync(@"C:\experiment\pdf\index.png");
var stream = await page.PdfStreamAsync(opts);
await page.PdfAsync(file2, opts);
await browser.CloseAsync();
return new FileStreamResult(stream, "application/pdf");
}
启动.cs
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
var bfOptions = new BrowserFetcherOptions();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
bfOptions.Path = Path.GetTempPath();
}
var bf = new BrowserFetcher(bfOptions);
bf.DownloadAsync(BrowserFetcher.DefaultRevision).Wait();
var info = new AppInfo
{
BrowserExecutablePath = bf.GetExecutablePath(BrowserFetcher.DefaultRevision)
};
var port = GetAvailablePort();
info.RazorPagesServerPort = port;
builder.Services.AddSingleton(info);
var webHost = Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(webBuilder =>
{
var scriptRoot = Environment.GetEnvironmentVariable("AzureWebJobsScriptRoot");
System.Console.WriteLine($"Starting web server on port {port}");
if (!string.IsNullOrEmpty(scriptRoot))
{
webBuilder.UseContentRoot(scriptRoot);
}
webBuilder.UseUrls($"http://0.0.0.0:{port}")
.UseStartup<RazorPagesApp.Startup>();
})
.Build();
webHost.Start();
}
private int GetAvailablePort()
{
// https://stackoverflow.com/a/150974/9035640
var listener = new TcpListener(IPAddress.Loopback, 0);
listener.Start();
int availablePort = ((IPEndPoint)listener.LocalEndpoint).Port;
listener.Stop();
return availablePort;
}
}
public class AppInfo
{
public string BrowserExecutablePath { get; set; }
public int RazorPagesServerPort { get; set; }
}
解决方案
根据您拥有的文档,ScreenShotDataAsync
它返回 a byte[]
:
byte[] data = await page.ScreenshotDataAsync(scrOpts);
还有ScreenshotStreamAsync
which 返回 a Stream
:
Stream stream = await page.ScreenshotStreamAsync(scrOpts);
推荐阅读
- python-3.x - 为条件测试覆盖 pathlib.Path.exists
- python - 如何将 Python Selenium 与 Electron JS 应用程序连接起来
- python - 尝试使用 python 在 Jupyter Notebook 中读取多个 .csv 文件时出错
- c# - 我的 c# 控制台应用程序不允许带有 Console.ReadLine() 的变量接收用户输入,而是从 1 向上计数
- python - Groupby 根据以前可用值和下一个可用值的平均值填充数据框中的缺失值
- gtk - 如何在 GTK Iconview 中垂直列出项目?
- javascript - localhost express mongodb server,fetch request到localhost返回400状态
- php - 根据下拉选择格式化用户文本
- python - Flask render_template 无法显示引用的模板
- selenium - 如何从机器人框架中的命令行参数获取测试用例传递中的变量