Skip to content

Commit d8a7a75

Browse files
committed
feat: 增加 AddBootstrapBlazorDom2ImageService 服务扩展
1 parent af388c5 commit d8a7a75

4 files changed

Lines changed: 203 additions & 0 deletions

File tree

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
// Website: https://www.blazor.zone or https://argozhang.github.io/
4+
5+
using BootstrapBlazor.Components;
6+
7+
namespace Microsoft.Extensions.DependencyInjection;
8+
9+
/// <summary>
10+
/// BootstrapBlazor 服务扩展类
11+
/// </summary>
12+
public static class BootstrapBlazorHtml2PdfServiceExtensions
13+
{
14+
/// <summary>
15+
/// 添加 AzureOpenAIService 服务
16+
/// </summary>
17+
/// <param name="services"></param>
18+
public static IServiceCollection AddBootstrapBlazorDom2ImageService(this IServiceCollection services)
19+
{
20+
services.AddScoped<IDom2ImageService, DefaultDom2ImageService>();
21+
#if NET8_0_OR_GREATER
22+
services.AddKeyedScoped<IDom2ImageService, DefaultDom2ImageService>("BootstrapBlazor.Dom2Image");
23+
#endif
24+
return services;
25+
}
26+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
// Website: https://www.blazor.zone or https://argozhang.github.io/
4+
5+
using Microsoft.Extensions.Logging;
6+
using Microsoft.JSInterop;
7+
8+
namespace BootstrapBlazor.Components;
9+
10+
/// <summary>
11+
/// 默认 Html to Image 实现
12+
/// <param name="runtime"></param>
13+
/// <param name="logger"></param>
14+
/// </summary>
15+
class DefaultDom2ImageService(IJSRuntime runtime, ILogger<DefaultDom2ImageService> logger) : IDom2ImageService
16+
{
17+
private JSModule? _jsModule;
18+
19+
/// <summary>
20+
/// <inheritdoc/>
21+
/// </summary>
22+
public async Task<string?> GetUrlAsync(string selector, Dom2ImageOptions? options = null, CancellationToken token = default)
23+
{
24+
string? data = null;
25+
try
26+
{
27+
_jsModule ??= await LoadModule();
28+
data = await _jsModule.InvokeAsync<string?>("getUrl", token, selector, options);
29+
}
30+
catch (OperationCanceledException) { }
31+
catch (Exception ex)
32+
{
33+
logger.LogError(ex, "{GetUrlAsync} throw exception", nameof(GetUrlAsync));
34+
}
35+
return data;
36+
}
37+
38+
/// <summary>
39+
/// <inheritdoc/>
40+
/// </summary>
41+
public async Task<Stream?> GetStreamAsync(string selector, Dom2ImageOptions? options = null, CancellationToken token = default)
42+
{
43+
Stream? data = null;
44+
try
45+
{
46+
_jsModule ??= await LoadModule();
47+
var streamReference = await _jsModule.InvokeAsync<IJSStreamReference?>("getStream", selector, options);
48+
if (streamReference != null)
49+
{
50+
data = await streamReference.OpenReadStreamAsync(streamReference.Length, token);
51+
}
52+
}
53+
catch (OperationCanceledException) { }
54+
catch (Exception ex)
55+
{
56+
logger.LogError(ex, "{GetUrlAsync} throw exception", nameof(GetUrlAsync));
57+
}
58+
return data;
59+
}
60+
61+
private Task<JSModule> LoadModule() => runtime.LoadModule("./_content/BootstrapBlazor.Dom2Image/dom2image.js");
62+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the Apache 2.0 License
3+
// See the LICENSE file in the project root for more information.
4+
// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone
5+
6+
using System.Text.Json.Serialization;
7+
8+
namespace BootstrapBlazor.Components;
9+
10+
/// <summary>
11+
/// Dom2ImageOptions 选项类
12+
/// </summary>
13+
public class Dom2ImageOptions
14+
{
15+
/// <summary>
16+
/// Removes redundant styles. Default value is true
17+
/// </summary>
18+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
19+
public bool? Compress { get; set; }
20+
21+
/// <summary>
22+
/// Skips idle delay for faster results. Default value is true
23+
/// </summary>
24+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
25+
public bool? Fast { get; set; }
26+
27+
/// <summary>
28+
/// Inlines fonts (icon fonts always embedded). Default value is false
29+
/// </summary>
30+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
31+
public bool? EmbedFonts { get; set; }
32+
33+
/// <summary>
34+
/// Output scale multiplier. Default value is 1
35+
/// </summary>
36+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
37+
public int? Scale { get; set; }
38+
39+
/// <summary>
40+
/// Device pixel ratio
41+
/// </summary>
42+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
43+
public int? Dpr { get; set; }
44+
45+
/// <summary>
46+
/// Output specific width size
47+
/// </summary>
48+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
49+
public int? Width { get; set; }
50+
51+
/// <summary>
52+
/// Output specific height size
53+
/// </summary>
54+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
55+
public int? Height { get; set; }
56+
57+
/// <summary>
58+
/// Fallback color for JPG/WebP. Default value is #fff
59+
/// </summary>
60+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
61+
public string? BackgroundColor { get; set; }
62+
63+
/// <summary>
64+
/// Quality for JPG/WebP (0 to 1)
65+
/// </summary>
66+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
67+
public float? Quality { get; set; }
68+
69+
/// <summary>
70+
/// Select png, jpg, webp Blob type. Default value is svg
71+
/// </summary>
72+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
73+
public string? Type { get; set; }
74+
75+
/// <summary>
76+
/// CSS selectors for elements to exclude
77+
/// </summary>
78+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
79+
public string[]? Exclude { get; set; }
80+
81+
/// <summary>
82+
///
83+
/// </summary>
84+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
85+
public string[]? LocalFonts { get; set; }
86+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
// Website: https://www.blazor.zone or https://argozhang.github.io/
4+
5+
namespace BootstrapBlazor.Components;
6+
7+
/// <summary>
8+
/// IDom2ImageService 接口定义
9+
/// </summary>
10+
public interface IDom2ImageService
11+
{
12+
/// <summary>
13+
/// 通过指定选择器获得 Html 元素返回图片数据
14+
/// </summary>
15+
/// <param name="selector"></param>
16+
/// <param name="options"></param>
17+
/// <param name="token"></param>
18+
/// <returns></returns>
19+
Task<string?> GetUrlAsync(string selector, Dom2ImageOptions? options = null, CancellationToken token = default);
20+
21+
/// <summary>
22+
/// 通过指定选择器获得 Html 元素返回图片数据流
23+
/// </summary>
24+
/// <param name="selector"></param>
25+
/// <param name="options"></param>
26+
/// <param name="token"></param>
27+
/// <returns></returns>
28+
Task<Stream?> GetStreamAsync(string selector, Dom2ImageOptions? options = null, CancellationToken token = default);
29+
}

0 commit comments

Comments
 (0)