编辑
2025-03-04
我当开发
00

目录

HTML转为图片输出
问题
契机
宽高问题
代码

HTML转为图片输出

HTML转为图片输出

问题

就是让AI 给我写了一个,将HTML片段转为图片的工具,比如这个Banner

<div style=" background: linear-gradient(135deg, #1a1a1a 0%, #0a3d62 100%); padding: 4rem 2rem; text-align: center; border-radius: 8px; border: 1px solid rgba(0, 255, 255, 0.2); box-shadow: 0 4px 20px rgba(0, 191, 255, 0.1); "> <h1 style=" color: #00ff88; font-family: Arial, sans-serif; font-size: 4rem; text-align: center; background: linear-gradient(90deg, #00ff88 0%, #00ffff 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; position: relative; text-transform: uppercase; letter-spacing: 4px; transition: 0.3s ease; transform: scale(1); filter: drop-shadow(0 0 40px #00ff88); ">HTML转为图片输出</h1> </div>

AI选用的是Puppeteer这个组件,我没接触过,反正就是能自己配置,谷歌 火狐什么的浏览器,代码的,没有界面,叫无头浏览器,路易十六很喜欢

然后各种问题,首先 Puppeteer 这玩意压根不能用,我让用C#写,写的方法名压根不对,可能是版本问题;然后自己下的Chrome浏览器内核也不能用,好不容易本地调试完了,Docker里又报错了;

契机

后来放弃了,调着调着发现服务器空间不够了,由于我一直瞎搞,100G 就玩Docker,玩没了,我就清理,后来发现一个 browserless/chrome,我也没用上啊,发现在 rsshub 里挂着,看着名字是浏览器,一艘还真是,rsshub就是用这个browserless监听网页变化的

要不说瞎折腾有好处,指不定哪就藏个路易十六

宽高问题

因为我就录入一个div,一段,这里的宽高就不是浏览器的高度,Puppeteer默认高度是600,继续问AI,改了一天也没改对;

最后是有两处,默认的高度要给够,写了个8000,然后再算一次,就是 document.querySelector('body > div').getBoundingClientRect().height,只能是元素的高度,body也不行,document也不行

代码

一共没多少行

c#
using Microsoft.AspNetCore.Mvc; using PuppeteerSharp; namespace HtmlToImageApi.Controllers { public class HtmlRequest { public string DIV { get; set; } public int MaxWidth { get; set; } = 600; } [ApiController] [Route("[controller]")] public class HtmlToImageController : ControllerBase { private readonly string _imageDirectory = $"{AppContext.BaseDirectory}images"; [HttpPost] public async Task<IActionResult> Post([FromBody] HtmlRequest _request) { var html = _request.DIV; if (string.IsNullOrEmpty(html)) { return BadRequest("HTML content is required."); } try { var browser = await Puppeteer.ConnectAsync(new ConnectOptions { BrowserWSEndpoint = "ws://browserless:1201",//browserless地址 DefaultViewport = new ViewPortOptions { Width = _request.MaxWidth, Height = 8000 } }); var page = await browser.NewPageAsync(); if (!html.Trim().StartsWith("<html", StringComparison.OrdinalIgnoreCase)) { html = $"<html><head><style>body {{ font-family: 'Noto Sans SC', sans-serif; margin: 0 auto;height: auto; }}</style></head><body>{html}</body></html>"; } await page.SetContentAsync(html); // 等待所有字体加载完成 await page.EvaluateFunctionAsync(@"async () => { await document.fonts.ready; }"); // 获取元素内容高度 var contentHeight = await page.EvaluateFunctionAsync<decimal>(@"() => { return document.querySelector('body > div').getBoundingClientRect().height; }"); var contentWidth = await page.EvaluateFunctionAsync<decimal>(@"() => { return document.querySelector('body > div').getBoundingClientRect().width; }"); // 根据内容高度重新设置视口 await page.SetViewportAsync(new ViewPortOptions { Width = Convert.ToInt32(contentWidth), Height = Convert.ToInt32(contentHeight) }); var fileName = $"{Guid.NewGuid()}.png"; var filePath = Path.Combine(_imageDirectory, fileName); await page.ScreenshotAsync(filePath, options: new ScreenshotOptions { FullPage = true, }); await browser.CloseAsync(); return Ok(fileName); } catch (Exception ex) { return StatusCode(500, $"Error: {ex.Message}"); } } } }

browserless Docker

yml
browserless: # marked image: browserless/chrome # marked restart: always # marked ulimits: # marked core: # marked hard: 0 # marked soft: 0 # marked healthcheck: test: - CMD - curl - -f - http://localhost:3000/pressure interval: 30s timeout: 10s retries: 3 ports: - 1201:3000

Dockerfile

yml
# 使用官方 ASP.NET Core 运行时镜像 FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base WORKDIR /app # 安装字体 RUN apt-get update && apt-get install -y fonts-noto-cjk fonts-noto-color-emoji # 使用官方 .NET Core SDK 镜像构建应用 FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build WORKDIR /src COPY ["HtmlToImageApi.csproj", "."] RUN dotnet restore "./HtmlToImageApi.csproj" COPY . . WORKDIR "/src/." RUN dotnet build "HtmlToImageApi.csproj" -c Release -o /app/build # 发布应用 FROM build AS publish RUN dotnet publish "HtmlToImageApi.csproj" -c Release -o /app/publish # 最终镜像 FROM base AS final WORKDIR /app COPY --from=publish /app/publish . EXPOSE 5000 ENTRYPOINT ["dotnet", "HtmlToImageApi.dll"]

3cf86a25-0275-493a-b0d9-6e7fb094634d.png

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:没想好

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!