From 61ca2b2f9fba764e0d0de21844deece181e3317e Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 17 Oct 2026 14:35:56 +0800 Subject: [PATCH 1/2] =?UTF-8?q?chore:=20=E7=B2=BE=E7=AE=80=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BootstrapBlazor.Extensions.slnx | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/BootstrapBlazor.Extensions.slnx b/BootstrapBlazor.Extensions.slnx index 8e2f9a36..088bbf7d 100644 --- a/BootstrapBlazor.Extensions.slnx +++ b/BootstrapBlazor.Extensions.slnx @@ -1,21 +1,4 @@ - - - - - - - - - - - - - - - - - @@ -93,7 +76,6 @@ - @@ -107,14 +89,6 @@ - - - - - - - - @@ -123,9 +97,6 @@ - - - From bb3ee3acfa5f50581c3cf52dc1695a62293d85b1 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 17 Oct 2026 14:51:11 +0800 Subject: [PATCH 2/2] =?UTF-8?q?chore:=20=E5=88=A0=E9=99=A4=E5=86=97?= =?UTF-8?q?=E4=BD=99=E4=B8=8D=E4=BD=BF=E7=94=A8=E7=9A=84=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...trapBlazor.BootstrapIcon.Extensions.csproj | 17 - .../DefaultIcon.cs | 225 ----------- .../ServiceCollectionExtensions.cs | 35 -- .../BootstrapBlazor.Core.csproj | 7 - src/components/BootstrapBlazor.Core/readme.md | 118 ------ ...rapBlazor.MaterialDesign.Extensions.csproj | 17 - .../DefaultIcon.cs | 225 ----------- .../ServiceCollectionExtensions.cs | 35 -- .../BootstrapBlazor.OCR/AiForm.razor | 37 -- .../BootstrapBlazor.OCR/AiForm.razor.cs | 180 --------- .../BootstrapBlazor.OCR/AiForm.razor.css | 19 - .../BootstrapBlazor.OCR/AiFormDocumentEmnu.cs | 44 --- .../BootstrapBlazor.OCR/AzureOpenAI.razor | 30 -- .../BootstrapBlazor.OCR/AzureOpenAI.razor.cs | 162 -------- .../BootstrapBlazor.OCR/AzureSTS.razor | 42 -- .../BootstrapBlazor.OCR/AzureSTS.razor.cs | 163 -------- .../BootstrapBlazor.OCR.csproj | 31 -- .../EnumAzureOpenAIModel.cs | 37 -- .../BootstrapBlazor.OCR/EnumVoiceName.cs | 167 -------- src/components/BootstrapBlazor.OCR/OCR.razor | 55 --- .../BootstrapBlazor.OCR/OCR.razor.cs | 349 ----------------- .../BootstrapBlazor.OCR/OCR.razor.css | 19 - .../BootstrapBlazor.OCR/PlayAudio.razor | 9 - .../BootstrapBlazor.OCR/PlayAudio.razor.cs | 172 --------- .../Services/AiFormService.cs | 170 -------- .../AiFormServiceCollectionExtensions.cs | 29 -- .../Services/BaseService.cs | 56 --- .../Services/OcrService.cs | 299 -------------- .../Services/OcrServiceAdv.cs | 365 ------------------ .../OcrServiceCollectionExtensions.cs | 31 -- .../Services/OpenAIClientService.cs | 98 ----- .../Services/StsService.cs | 161 -------- .../Services/TranslateService.cs | 134 ------- .../BootstrapBlazor.OCR/Translate.razor | 41 -- .../BootstrapBlazor.OCR/Translate.razor.cs | 99 ----- .../BootstrapBlazor.OCR/Utils/Utils.cs | 76 ---- .../BootstrapBlazor.OCR/wwwroot/app.js | 7 - .../BootstrapBlazor.OCR/wwwroot/audio.js | 47 --- .../wwwroot/images/celebrities.jpg | Bin 81732 -> 0 bytes .../wwwroot/images/libai.jpg | Bin 65839 -> 0 bytes .../wwwroot/images/objects.jpg | Bin 37849 -> 0 bytes .../wwwroot/images/printed_text.jpg | Bin 112538 -> 0 bytes .../BootstrapBlazor.WebSerialPort.csproj | 20 - .../WebSerial.razor | 32 -- .../WebSerial.razor.cs | 338 ---------------- .../WebSerial.razor.js | 339 ---------------- .../WebSerialOptions.cs | 277 ------------- .../wwwroot/background.png | Bin 378 -> 0 bytes .../wwwroot/exampleJsInterop.js | 6 - .../BootstrapBlazor.TouchSocket.csproj | 32 -- .../Extensions/ServiceCollectionExtensions.cs | 24 -- .../Services/DefaultTcpSocketProvider.cs | 123 ------ 52 files changed, 4999 deletions(-) delete mode 100644 src/components/BootstrapBlazor.BootstrapIcon.Extensions/BootstrapBlazor.BootstrapIcon.Extensions.csproj delete mode 100644 src/components/BootstrapBlazor.BootstrapIcon.Extensions/DefaultIcon.cs delete mode 100644 src/components/BootstrapBlazor.BootstrapIcon.Extensions/ServiceCollectionExtensions.cs delete mode 100644 src/components/BootstrapBlazor.Core/BootstrapBlazor.Core.csproj delete mode 100644 src/components/BootstrapBlazor.Core/readme.md delete mode 100644 src/components/BootstrapBlazor.MaterialDesign.Extensions/BootstrapBlazor.MaterialDesign.Extensions.csproj delete mode 100644 src/components/BootstrapBlazor.MaterialDesign.Extensions/DefaultIcon.cs delete mode 100644 src/components/BootstrapBlazor.MaterialDesign.Extensions/ServiceCollectionExtensions.cs delete mode 100644 src/components/BootstrapBlazor.OCR/AiForm.razor delete mode 100644 src/components/BootstrapBlazor.OCR/AiForm.razor.cs delete mode 100644 src/components/BootstrapBlazor.OCR/AiForm.razor.css delete mode 100644 src/components/BootstrapBlazor.OCR/AiFormDocumentEmnu.cs delete mode 100644 src/components/BootstrapBlazor.OCR/AzureOpenAI.razor delete mode 100644 src/components/BootstrapBlazor.OCR/AzureOpenAI.razor.cs delete mode 100644 src/components/BootstrapBlazor.OCR/AzureSTS.razor delete mode 100644 src/components/BootstrapBlazor.OCR/AzureSTS.razor.cs delete mode 100644 src/components/BootstrapBlazor.OCR/BootstrapBlazor.OCR.csproj delete mode 100644 src/components/BootstrapBlazor.OCR/EnumAzureOpenAIModel.cs delete mode 100644 src/components/BootstrapBlazor.OCR/EnumVoiceName.cs delete mode 100644 src/components/BootstrapBlazor.OCR/OCR.razor delete mode 100644 src/components/BootstrapBlazor.OCR/OCR.razor.cs delete mode 100644 src/components/BootstrapBlazor.OCR/OCR.razor.css delete mode 100644 src/components/BootstrapBlazor.OCR/PlayAudio.razor delete mode 100644 src/components/BootstrapBlazor.OCR/PlayAudio.razor.cs delete mode 100644 src/components/BootstrapBlazor.OCR/Services/AiFormService.cs delete mode 100644 src/components/BootstrapBlazor.OCR/Services/AiFormServiceCollectionExtensions.cs delete mode 100644 src/components/BootstrapBlazor.OCR/Services/BaseService.cs delete mode 100644 src/components/BootstrapBlazor.OCR/Services/OcrService.cs delete mode 100644 src/components/BootstrapBlazor.OCR/Services/OcrServiceAdv.cs delete mode 100644 src/components/BootstrapBlazor.OCR/Services/OcrServiceCollectionExtensions.cs delete mode 100644 src/components/BootstrapBlazor.OCR/Services/OpenAIClientService.cs delete mode 100644 src/components/BootstrapBlazor.OCR/Services/StsService.cs delete mode 100644 src/components/BootstrapBlazor.OCR/Services/TranslateService.cs delete mode 100644 src/components/BootstrapBlazor.OCR/Translate.razor delete mode 100644 src/components/BootstrapBlazor.OCR/Translate.razor.cs delete mode 100644 src/components/BootstrapBlazor.OCR/Utils/Utils.cs delete mode 100644 src/components/BootstrapBlazor.OCR/wwwroot/app.js delete mode 100644 src/components/BootstrapBlazor.OCR/wwwroot/audio.js delete mode 100644 src/components/BootstrapBlazor.OCR/wwwroot/images/celebrities.jpg delete mode 100644 src/components/BootstrapBlazor.OCR/wwwroot/images/libai.jpg delete mode 100644 src/components/BootstrapBlazor.OCR/wwwroot/images/objects.jpg delete mode 100644 src/components/BootstrapBlazor.OCR/wwwroot/images/printed_text.jpg delete mode 100644 src/components/BootstrapBlazor.WebSerialPort/BootstrapBlazor.WebSerialPort.csproj delete mode 100644 src/components/BootstrapBlazor.WebSerialPort/WebSerial.razor delete mode 100644 src/components/BootstrapBlazor.WebSerialPort/WebSerial.razor.cs delete mode 100644 src/components/BootstrapBlazor.WebSerialPort/WebSerial.razor.js delete mode 100644 src/components/BootstrapBlazor.WebSerialPort/WebSerialOptions.cs delete mode 100644 src/components/BootstrapBlazor.WebSerialPort/wwwroot/background.png delete mode 100644 src/components/BootstrapBlazor.WebSerialPort/wwwroot/exampleJsInterop.js delete mode 100644 src/extensions/BootstrapBlazor.TouchSocket/BootstrapBlazor.TouchSocket.csproj delete mode 100644 src/extensions/BootstrapBlazor.TouchSocket/Extensions/ServiceCollectionExtensions.cs delete mode 100644 src/extensions/BootstrapBlazor.TouchSocket/Services/DefaultTcpSocketProvider.cs diff --git a/src/components/BootstrapBlazor.BootstrapIcon.Extensions/BootstrapBlazor.BootstrapIcon.Extensions.csproj b/src/components/BootstrapBlazor.BootstrapIcon.Extensions/BootstrapBlazor.BootstrapIcon.Extensions.csproj deleted file mode 100644 index 003af8df..00000000 --- a/src/components/BootstrapBlazor.BootstrapIcon.Extensions/BootstrapBlazor.BootstrapIcon.Extensions.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - 9.1.0 - - - - Bootstrap Blazor WebAssembly wasm UI Components Icon Theme - Bootstrap UI components extensions of Bootstrap Icons - BootstrapBlazor.Components - - - - - - - diff --git a/src/components/BootstrapBlazor.BootstrapIcon.Extensions/DefaultIcon.cs b/src/components/BootstrapBlazor.BootstrapIcon.Extensions/DefaultIcon.cs deleted file mode 100644 index 6dc493a3..00000000 --- a/src/components/BootstrapBlazor.BootstrapIcon.Extensions/DefaultIcon.cs +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -namespace BootstrapBlazor.Components; - -internal class DefaultIcon -{ - public static Dictionary Icons => new() - { - // AnchorLink 组件 - { ComponentIcons.AnchorLinkIcon, "bi bi-link-45deg" }, - - // Avatar 组件 - { ComponentIcons.AvatarIcon, "bi bi-person-fill" }, - { ComponentIcons.AutoFillIcon, "bi bi-chevron-up" }, - { ComponentIcons.AutoCompleteIcon, "bi bi-chevron-up" }, - - { ComponentIcons.ButtonLoadingIcon, "bi bi-arrow-clockwise bi-spin" }, - - { ComponentIcons.CaptchaRefreshIcon, "bi bi-arrow-clockwise" }, - { ComponentIcons.CaptchaBarIcon, "bi bi-chevron-right" }, - { ComponentIcons.CameraPlayIcon, "bi bi-circle-play" }, - { ComponentIcons.CameraStopIcon, "bi bi-circle-stop" }, - { ComponentIcons.CameraPhotoIcon, "bi bi-camera" }, - { ComponentIcons.CardCollapseIcon, "bi bi-arrow-right-circle-fill" }, - { ComponentIcons.CarouselPreviousIcon, "bi bi-chevron-left" }, - { ComponentIcons.CarouselNextIcon, "bi bi-chevron-right" }, - { ComponentIcons.CascaderIcon, "bi bi-chevron-up" }, - { ComponentIcons.CascaderSubMenuIcon, "bi bi-chevron-down" }, - { ComponentIcons.ConsoleClearButtonIcon, "bi bi-x" }, - - // DateTimePicker 组件 - { ComponentIcons.DatePickBodyPreviousYearIcon, "bi bi-chevron-double-left" }, - { ComponentIcons.DatePickBodyPreviousMonthIcon, "bi bi-chevron-left" }, - { ComponentIcons.DatePickBodyNextMonthIcon, "bi bi-chevron-right" }, - { ComponentIcons.DatePickBodyNextYearIcon, "bi bi-chevron-double-right" }, - { ComponentIcons.DateTimePickerIcon, "bi bi-calendar" }, - { ComponentIcons.TimePickerCellUpIcon, "bi bi-chevron-up" }, - { ComponentIcons.TimePickerCellDownIcon, "bi bi-chevron-down" }, - - // DateTimeRange 组件 - { ComponentIcons.DateTimeRangeIcon, "bi bi-calendar-range" }, - { ComponentIcons.DateTimeRangeClearIcon, "bi bi-x-circle" }, - - { ComponentIcons.DialogCloseButtonIcon, "bi bi-x" }, - { ComponentIcons.DialogSaveButtonIcon, "bi bi-check" }, - { ComponentIcons.DialogMaximizeWindowIcon, "bi bi-window" }, - { ComponentIcons.DialogRestoreWindowIcon, "bi bi-window-stack" }, - - { ComponentIcons.TopMenuDropdownIcon, "bi bi-chevron-down" }, - { ComponentIcons.SideMenuDropdownIcon, "bi bi-chevron-down" }, - { ComponentIcons.MenuLinkArrowIcon, "bi bi-chevron-left" }, - - { ComponentIcons.ResultDialogYesIcon, "bi bi-check" }, - { ComponentIcons.ResultDialogNoIcon, "bi bi-x" }, - { ComponentIcons.ResultDialogCloseIcon, "bi bi-x" }, - - { ComponentIcons.SearchDialogClearIcon, "bi bi-trash3" }, - { ComponentIcons.SearchDialogSearchIcon, "bi bi-search" }, - - { ComponentIcons.StepIcon, "bi bi-check" }, - { ComponentIcons.StepErrorIcon, "bi bi-x" }, - - { ComponentIcons.FilterButtonFilterIcon, "bi bi-funnel-fill" }, - { ComponentIcons.FilterButtonClearIcon, "bi bi-funnel" }, - - { ComponentIcons.TableFilterPlusIcon, "bi bi-plus" }, - { ComponentIcons.TableFilterMinusIcon, "bi bi-dash" }, - - { ComponentIcons.FullScreenButtonIcon, "bi bi-arrows-fullscreen" }, - { ComponentIcons.FullScreenExitButtonIcon, "bi bi-fullscreen-exit" }, - - { ComponentIcons.GoTopIcon, "bi bi-chevron-up" }, - - { ComponentIcons.ImagePreviewPreviousIcon, "bi bi-chevron-left" }, - { ComponentIcons.ImagePreviewNextIcon, "bi bi-chevron-right" }, - { ComponentIcons.ImagePreviewMinusIcon, "bi bi-search" }, - { ComponentIcons.ImagePreviewPlusIcon, "bi bi-search" }, - { ComponentIcons.ImagePreviewRotateLeftIcon, "bi bi-arrow-counterclockwise" }, - { ComponentIcons.ImagePreviewRotateRightIcon, "bi bi-arrow-clockwise" }, - - { ComponentIcons.ImageViewerFileIcon, "bi bi-file-image" }, - - { ComponentIcons.InputClearIcon, "bi bi-x-circle" }, - - { ComponentIcons.InputNumberMinusIcon, "bi bi-dash-circle" }, - { ComponentIcons.InputNumberPlusIcon, "bi bi-plus-circle" }, - - { ComponentIcons.LayoutMenuBarIcon, "bi bi-list" }, - { ComponentIcons.LogoutLinkIcon, "bi bi-box-arrow-right" }, - - { ComponentIcons.LoadingIcon, "bi bi-arrow-clockwise bi-spin" }, - - { ComponentIcons.PaginationPrevPageIcon, "bi bi-chevron-left" }, - { ComponentIcons.PaginationNextPageIcon, "bi bi-chevron-right" }, - { ComponentIcons.PaginationPrevEllipsisPageIcon, "bi bi-three-dots" }, - { ComponentIcons.PaginationNextEllipsisPageIcon, "bi bi-three-dots" }, - - { ComponentIcons.PopConfirmButtonConfirmIcon, "bi bi-exclamation-circle" }, - - { ComponentIcons.RateStarIcon, "bi bi-star-fill" }, - { ComponentIcons.RateUnStarIcon, "bi bi-star" }, - - { ComponentIcons.RibbonTabArrowUpIcon, "bi bi-chevron-up" }, - { ComponentIcons.RibbonTabArrowDownIcon, "bi bi-chevron-down" }, - { ComponentIcons.RibbonTabArrowPinIcon, "bi bi-pin bi-pin-angle" }, - - { ComponentIcons.MultiSelectDropdownIcon, "bi bi-chevron-up" }, - { ComponentIcons.MultiSelectClearIcon, "bi bi-x" }, - - { ComponentIcons.SelectTreeDropdownIcon, "bi bi-chevron-up" }, - - { ComponentIcons.SearchClearButtonIcon, "bi bi-trash3" }, - { ComponentIcons.SearchButtonIcon, "bi bi-search" }, - { ComponentIcons.SearchButtonLoadingIcon, "bi bi-arrow-clockwise bi-spin" }, - - { ComponentIcons.SelectDropdownIcon, "bi bi-chevron-up" }, - { ComponentIcons.SelectClearIcon, "bi bi-x-circle" }, - { ComponentIcons.SelectSearchIcon, "bi bi-search" }, - - { ComponentIcons.SweetAlertCloseIcon, "bi bi-x" }, - { ComponentIcons.SweetAlertConfirmIcon, "bi bi-check" }, - - { ComponentIcons.PrintButtonIcon, "bi bi-printer" }, - - { ComponentIcons.ToastSuccessIcon, "bi bi-check-circle" }, - { ComponentIcons.ToastInformationIcon, "bi bi-exclamation-circle" }, - { ComponentIcons.ToastWarningIcon, "bi bi-exclamation-triangle" }, - { ComponentIcons.ToastErrorIcon, "bi bi-x-circle" }, - - { ComponentIcons.TabPreviousIcon, "bi bi-chevron-left" }, - { ComponentIcons.TabNextIcon, "bi bi-chevron-right" }, - { ComponentIcons.TabDropdownIcon, "bi bi-chevron-down" }, - { ComponentIcons.TabCloseIcon, "bi bi-x" }, - - { ComponentIcons.TableColumnToolboxIcon, "bi bi-gear" }, - - { ComponentIcons.TableSortIconAsc, "bi bi-sort-up-alt" }, - { ComponentIcons.TableSortDesc, "bi bi-sort-down" }, - { ComponentIcons.TableSortIcon, "bi bi-filter" }, - { ComponentIcons.TableFilterIcon, "bi bi-funnel" }, - { ComponentIcons.TableExportButtonIcon, "bi bi-download" }, - - { ComponentIcons.TableAddButtonIcon, "bi bi-plus" }, - { ComponentIcons.TableEditButtonIcon, "bi bi-check2-square" }, - { ComponentIcons.TableDeleteButtonIcon, "bi bi-x" }, - { ComponentIcons.TableRefreshButtonIcon, "bi bi-arrow-clockwise" }, - { ComponentIcons.TableCardViewButtonIcon, "bi bi-list" }, - { ComponentIcons.TableColumnListButtonIcon, "bi bi-list-check" }, - { ComponentIcons.TableExportCsvIcon, "bi bi-filetype-csv" }, - { ComponentIcons.TableExportExcelIcon, "bi bi-filetype-xlsx" }, - { ComponentIcons.TableExportPdfIcon, "bi bi-filetype-pdf" }, - { ComponentIcons.TableSearchButtonIcon, "bi bi-search" }, - { ComponentIcons.TableResetSearchButtonIcon, "bi bi-trash3" }, - { ComponentIcons.TableCloseButtonIcon, "bi bi-x" }, - { ComponentIcons.TableCancelButtonIcon, "bi bi-x" }, - { ComponentIcons.TableSaveButtonIcon, "bi bi-check" }, - { ComponentIcons.TableAdvanceButtonIcon, "bi bi-search" }, - { ComponentIcons.TableAdvancedSortButtonIcon, "bi bi-sort-alpha-up" }, - - { ComponentIcons.TableTreeIcon, "bi bi-caret-right-fill" }, - { ComponentIcons.TableTreeExpandIcon, "bi bi-caret-right-fill bi-rotate-90" }, - { ComponentIcons.TableTreeNodeLoadingIcon, "bi bi-arrow-clockwise bi-spin" }, - { ComponentIcons.TableCopyColumnButtonIcon, "bi bi-clipboard" }, - { ComponentIcons.TableGearIcon, "bi bi-gear" }, - - { ComponentIcons.TransferLeftIcon, "bi bi-chevron-left" }, - { ComponentIcons.TransferRightIcon, "bi bi-chevron-right" }, - { ComponentIcons.TransferPanelSearchIcon, "bi bi-search" }, - - { ComponentIcons.TimerIcon, "bi bi-bell" }, - - { ComponentIcons.TreeViewExpandNodeIcon, "bi bi-caret-right-fill bi-rotate-90" }, - { ComponentIcons.TreeViewNodeIcon, "bi bi-caret-right-fill" }, - { ComponentIcons.TreeViewSearchIcon, "bi bi-search" }, - { ComponentIcons.TreeViewResetSearchIcon, "bi bi-backspace" }, - - // Upload - { ComponentIcons.AvatarUploadDeleteIcon, "bi bi-trash3" }, - { ComponentIcons.AvatarUploadLoadingIcon, "bi bi-arrow-clockwise bi-spin" }, - { ComponentIcons.AvatarUploadAddIcon, "bi bi-plus" }, - { ComponentIcons.AvatarUploadValidStatusIcon, "bi bi-check bi-rotate-315" }, - { ComponentIcons.AvatarUploadInvalidStatusIcon, "bi bi-x bi-rotate-315" }, - - { ComponentIcons.ButtonUploadBrowserButtonIcon, "bi bi-folder2-open" }, - { ComponentIcons.ButtonUploadLoadingIcon, "bi bi-arrow-clockwise bi-spin" }, - { ComponentIcons.ButtonUploadInvalidStatusIcon, "bi bi-x-circle" }, - { ComponentIcons.ButtonUploadValidStatusIcon, "bi bi-check-circle" }, - { ComponentIcons.ButtonUploadDeleteIcon, "bi bi-trash3" }, - { ComponentIcons.ButtonUploadDownloadIcon, "bi bi-cloud-download" }, - - { ComponentIcons.InputUploadBrowserButtonIcon, "bi bi-folder-open" }, - { ComponentIcons.InputUploadDeleteButtonIcon, "bi bi-trash3" }, - - { ComponentIcons.CardUploadAddIcon, "bi bi-plus" }, - { ComponentIcons.CardUploadStatusIcon, "bi bi-check bi-rotate-315" }, - { ComponentIcons.CardUploadDeleteIcon, "bi bi-x bi-rotate-315" }, - { ComponentIcons.CardUploadRemoveIcon, "bi bi-trash3" }, - { ComponentIcons.CardUploadDownloadIcon, "bi bi-cloud-download" }, - { ComponentIcons.CardUploadZoomIcon, "bi bi-search" }, - { ComponentIcons.UploadCancelIcon, "bi bi-cancel" }, - - { ComponentIcons.FileIconExcel, "bi bi-filetype-xlsx" }, - { ComponentIcons.FileIconDocx, "bi bi-filetype-docx" }, - { ComponentIcons.FileIconPPT, "bi bi-filetype-pptx" }, - { ComponentIcons.FileIconAudio, "bi bi-filetype-mp4" }, - { ComponentIcons.FileIconVideo, "bi bi-filetype-mov" }, - { ComponentIcons.FileIconCode, "bi bi-filetype-cs" }, - { ComponentIcons.FileIconPdf, "bi bi-filetype-pdf" }, - { ComponentIcons.FileIconZip, "bi bi-filetype-raw" }, - { ComponentIcons.FileIconArchive, "bi bi-filetype-aac" }, - { ComponentIcons.FileIconImage, "bi bi-filetype-png" }, - { ComponentIcons.FileIconFile, "bi bi-filetype-txt" }, - - { ComponentIcons.QueryBuilderPlusIcon, "bi bi-plus" }, - { ComponentIcons.QueryBuilderMinusIcon, "bi bi-dash" }, - { ComponentIcons.QueryBuilderRemoveIcon, "bi bi-x" }, - - { ComponentIcons.ThemeProviderAutoModeIcon, "bi bi-circle-half" }, - { ComponentIcons.ThemeProviderLightModeIcon, "bi bi-sun-fill" }, - { ComponentIcons.ThemeProviderDarkModeIcon, "bi bi-moon-stars-fill" }, - { ComponentIcons.ThemeProviderActiveModeIcon, "bi bi-check2" } - }; -} diff --git a/src/components/BootstrapBlazor.BootstrapIcon.Extensions/ServiceCollectionExtensions.cs b/src/components/BootstrapBlazor.BootstrapIcon.Extensions/ServiceCollectionExtensions.cs deleted file mode 100644 index f67179a9..00000000 --- a/src/components/BootstrapBlazor.BootstrapIcon.Extensions/ServiceCollectionExtensions.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -#if NET8_0_OR_GREATER -using System.Collections.Frozen; -#endif - -using BootstrapBlazor.Components; - -namespace Microsoft.Extensions.DependencyInjection; - -/// -/// BootstrapBlazor 服务扩展类 -/// -public static class IconMapperOptionsExtensions -{ - /// - /// 添加 Bootstrap 图标主题服务 - /// - /// - public static IServiceCollection ConfigureBootstrapIconTheme(this IServiceCollection services) - { - services.ConfigureIconThemeOptions(options => - { - options.ThemeKey = "bootstrap"; -#if NET8_0_OR_GREATER - options.TryAddIcons("bootstrap", DefaultIcon.Icons.ToFrozenDictionary()); -#else - options.Icons["bootstrap"] = DefaultIcon.Icons; -#endif - }); - return services; - } -} diff --git a/src/components/BootstrapBlazor.Core/BootstrapBlazor.Core.csproj b/src/components/BootstrapBlazor.Core/BootstrapBlazor.Core.csproj deleted file mode 100644 index eef41b84..00000000 --- a/src/components/BootstrapBlazor.Core/BootstrapBlazor.Core.csproj +++ /dev/null @@ -1,7 +0,0 @@ - - - - 9.0.0 - - - diff --git a/src/components/BootstrapBlazor.Core/readme.md b/src/components/BootstrapBlazor.Core/readme.md deleted file mode 100644 index 5d2a241a..00000000 --- a/src/components/BootstrapBlazor.Core/readme.md +++ /dev/null @@ -1,118 +0,0 @@ -# Bootstrap Blazor Component - -## A set of enterprise-class UI components based on Bootstrap and Blazor. - -[![License](https://img.shields.io/github/license/dotnetcore/bootstrapblazor.svg?logo=git&logoColor=red)](https://github.com/dotnetcore/BootstrapBlazor/blob/main/LICENSE) -[![Github build](https://img.shields.io/github/actions/workflow/status/dotnetcore/BootstrapBlazor/build.yml?branch=main&?label=main&logo=github)](https://github.com/dotnetcore/BootstrapBlazor/actions?query=workflow%3A%22Build+Project%22+branch%3Amain) -[![Repo Size](https://img.shields.io/github/repo-size/dotnetcore/BootstrapBlazor.svg?logo=github&logoColor=green&label=repo)](https://github.com/dotnetcore/BootstrapBlazor) -[![Commit Date](https://img.shields.io/github/last-commit/dotnetcore/BootstrapBlazor/main.svg?logo=github&logoColor=green&label=commit)](https://github.com/dotnetcore/BootstrapBlazor) -[![codecov](https://codecov.io/gh/dotnetcore/BootstrapBlazor/branch/main/graph/badge.svg?token=5SXIWHXZC3)](https://codecov.io/gh/dotnetcore/BootstrapBlazor) - ---- - -## Features -- Enterprise-class UI designed for web applications. -- A set of high-quality Blazor components out of the box. -- Supports WebAssembly-based client-side and SignalR-based server-side UI event interaction. -- Supports Progressive Web Applications (PWA). -- Build with C#, a multi-paradigm static language for an efficient development experience. -- .NET Standard 2.1 based, with direct reference to the rich .NET ecosystem. -- Supports NET5. (Server-Side, WASM) -- Seamless integration with existing ASP.NET Core MVC and Razor Pages projects. - -## Online Examples -[![website](https://img.shields.io/badge/China-https://www.blazor.zone-success.svg?color=red&logo=buzzfeed&logoColor=green)](https://www.blazor.zone) - -## Installation Guide - -- Install .net core sdk [Official website](https://dotnet.microsoft.com/download) -- Install Visual Studio 2019 lastest [Official website](https://visualstudio.microsoft.com/vs/getting-started/) - -```shell -git clone https://github.com/dotnetcore/BootstrapBlazor.git -cd BootstrapBlazor/src/BootstrapBlazor.Server -dotnet run -``` - -## Create a new project from the dotnet new template - -1. Install the template - -`dotnet new install Bootstrap.Blazor.Templates::*` - -2. Create the Boilerplate project with the template - -`dotnet new bbapp` - -## Install Bootstrap Blazor Project Template - -1. Download Project Template - -Microsoft Market [link](https://marketplace.visualstudio.com/items?itemName=Longbow.BootstrapBlazorUITemplate) - -2. Double Click **BootstrapBlazor.UITemplate.vsix** - -## Import Bootstrap Blazor into an existing project - -1. Go to the project folder of the application and install the Nuget package reference - -`dotnet add package BootstrapBlazor` - -2. **Add** the `stylesheet` `javascripts` file to your main index file - `Pages/_Host.cshtml (Server)` or `wwwroot/index.html (WebAssembly)` - - **HTML** - -``` - - - - . . . - - - - . . . - - - - -``` - -3. Open the `~/Startup.cs` file in the and register the `Bootstrap Blazor` service: - - **C#** - -``` -namespace BootstrapBlazorAppName -{ - public class Startup - { - public void ConfigureServices(IServiceCollection services) - { - //more code may be present here - services.AddBootstrapBlazor(); - } - - //more code may be present here - } -} -``` - -## Visual Studio Integration - -To create a new `Bootstrap Blazor` UI for Blazor application, use the Create New Project Wizard. The wizard detects all installed versions of `Bootstrap Blazor` for Blazor and lists them in the Version combobox—this enables you to start your project with the desired version. You can also get the latest version to make sure you are up to date. - -1. Get the Wizard - -To use the Create New Project Wizard, install the `Bootstrap Blazor` UI for Blazor Visual Studio Extensions. You can get it from the: - -- Visual Studio Marketplace (for Windows) - -2. Start the Wizard - -To start the wizard, use either of the following approaches - -### Using the Project menu: - -- Click File > New > Project. -- Find and click the C# Blazor Application option (you can use the search, or filter by Blazor templates). -- Follow the wizard. diff --git a/src/components/BootstrapBlazor.MaterialDesign.Extensions/BootstrapBlazor.MaterialDesign.Extensions.csproj b/src/components/BootstrapBlazor.MaterialDesign.Extensions/BootstrapBlazor.MaterialDesign.Extensions.csproj deleted file mode 100644 index 4c1457e8..00000000 --- a/src/components/BootstrapBlazor.MaterialDesign.Extensions/BootstrapBlazor.MaterialDesign.Extensions.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - 9.1.0 - - - - Bootstrap Blazor WebAssembly wasm UI Components Icon Theme - Bootstrap UI components extensions of Meterial Icons - BootstrapBlazor.Components - - - - - - - diff --git a/src/components/BootstrapBlazor.MaterialDesign.Extensions/DefaultIcon.cs b/src/components/BootstrapBlazor.MaterialDesign.Extensions/DefaultIcon.cs deleted file mode 100644 index cfd3bd0a..00000000 --- a/src/components/BootstrapBlazor.MaterialDesign.Extensions/DefaultIcon.cs +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -namespace BootstrapBlazor.Components; - -internal class DefaultIcon -{ - public static Dictionary Icons => new() - { - // AnchorLink 组件 - { ComponentIcons.AnchorLinkIcon, "mdi mdi-link-variant" }, - - // Avatar 组件 - { ComponentIcons.AvatarIcon, "mdi mdi-account" }, - { ComponentIcons.AutoFillIcon, "mdi mdi-chevron-up" }, - { ComponentIcons.AutoCompleteIcon, "mdi mdi-chevron-up" }, - - { ComponentIcons.ButtonLoadingIcon, "mdi mdi-loading mdi-spin" }, - - { ComponentIcons.CaptchaRefreshIcon, "mdi mdi-refresh" }, - { ComponentIcons.CaptchaBarIcon, "mdi mdi-chevron-right" }, - { ComponentIcons.CameraPlayIcon, "mdi mdi-play-circle-outline" }, - { ComponentIcons.CameraStopIcon, "mdi mdi-stop-circle-outline" }, - { ComponentIcons.CameraPhotoIcon, "mdi mdi-camera-outline" }, - { ComponentIcons.CardCollapseIcon, "mdi mdi-chevron-right-circle" }, - { ComponentIcons.CarouselPreviousIcon, "mdi mdi-chevron-left" }, - { ComponentIcons.CarouselNextIcon, "mdi mdi-chevron-right" }, - { ComponentIcons.CascaderIcon, "mdi mdi-chevron-up" }, - { ComponentIcons.CascaderSubMenuIcon, "mdi mdi-chevron-down" }, - { ComponentIcons.ConsoleClearButtonIcon, "mdi mdi-close" }, - - // DateTimePicker 组件 - { ComponentIcons.DatePickBodyPreviousYearIcon, "mdi mdi-chevron-double-left" }, - { ComponentIcons.DatePickBodyPreviousMonthIcon, "mdi mdi-chevron-left" }, - { ComponentIcons.DatePickBodyNextMonthIcon, "mdi mdi-chevron-right" }, - { ComponentIcons.DatePickBodyNextYearIcon, "mdi mdi-chevron-double-right" }, - { ComponentIcons.DateTimePickerIcon, "mdi mdi-calendar-outline" }, - { ComponentIcons.TimePickerCellUpIcon, "mdi mdi-chevron-up" }, - { ComponentIcons.TimePickerCellDownIcon, "mdi mdi-chevron-down" }, - - // DateTimeRange 组件 - { ComponentIcons.DateTimeRangeIcon, "mdi mdi-calendar-range-outline" }, - { ComponentIcons.DateTimeRangeClearIcon, "mdi mdi-close-circle-outline" }, - - { ComponentIcons.DialogCloseButtonIcon, "mdi mdi-close" }, - { ComponentIcons.DialogSaveButtonIcon, "mdi mdi-content-save" }, - { ComponentIcons.DialogMaximizeWindowIcon, "mdi mdi-window-maximize" }, - { ComponentIcons.DialogRestoreWindowIcon, "mdi mdi-window-restore" }, - - { ComponentIcons.TopMenuDropdownIcon, "mdi mdi-chevron-down" }, - { ComponentIcons.SideMenuDropdownIcon, "mdi mdi-chevron-down" }, - { ComponentIcons.MenuLinkArrowIcon, "mdi mdi-chevron-left" }, - - { ComponentIcons.ResultDialogYesIcon, "mdi mdi-check" }, - { ComponentIcons.ResultDialogNoIcon, "mdi mdi-close-circle-outline" }, - { ComponentIcons.ResultDialogCloseIcon, "mdi mdi-close-circle-outline" }, - - { ComponentIcons.SearchDialogClearIcon, "mdi mdi-trash-can-outline" }, - { ComponentIcons.SearchDialogSearchIcon, "mdi mdi-magnify-plus-outline" }, - - { ComponentIcons.StepIcon, "mdi mdi-check" }, - { ComponentIcons.StepErrorIcon, "mdi mdi-close" }, - - { ComponentIcons.FilterButtonFilterIcon, "mdi mdi-filter-outline" }, - { ComponentIcons.FilterButtonClearIcon, "mdi mdi-filter-remove-outline" }, - - { ComponentIcons.TableFilterPlusIcon, "mdi mdi-plus" }, - { ComponentIcons.TableFilterMinusIcon, "mdi mdi-minus" }, - - { ComponentIcons.FullScreenButtonIcon, "mdi mdi-arrow-expand-all" }, - { ComponentIcons.FullScreenExitButtonIcon, "mdi mdi-fullscreen-exit" }, - - { ComponentIcons.GoTopIcon, "mdi mdi-chevron-up" }, - - { ComponentIcons.ImagePreviewPreviousIcon, "mdi mdi-chevron-left" }, - { ComponentIcons.ImagePreviewNextIcon, "mdi mdi-chevron-right" }, - { ComponentIcons.ImagePreviewMinusIcon, "mdi mdi-magnify-minus-outline" }, - { ComponentIcons.ImagePreviewPlusIcon, "mdi mdi-magnify-plus-outline" }, - { ComponentIcons.ImagePreviewRotateLeftIcon, "mdi mdi-file-rotate-left-outline" }, - { ComponentIcons.ImagePreviewRotateRightIcon, "mdi mdi-file-rotate-right-outline" }, - - { ComponentIcons.ImageViewerFileIcon, "mdi mdi-file-image-outline" }, - - { ComponentIcons.InputClearIcon, "mdi mdi-close-circle-outline" }, - - { ComponentIcons.InputNumberMinusIcon, "mdi mdi-minus-circle-outline" }, - { ComponentIcons.InputNumberPlusIcon, "mdi mdi-plus-circle-outline" }, - - { ComponentIcons.LayoutMenuBarIcon, "mdi mdi-menu" }, - { ComponentIcons.LogoutLinkIcon, "mdi mdi-logout" }, - - { ComponentIcons.LoadingIcon, "mdi mdi-loading mdi-spin" }, - - { ComponentIcons.PaginationPrevPageIcon, "mdi mdi-chevron-left" }, - { ComponentIcons.PaginationNextPageIcon, "mdi mdi-chevron-right" }, - { ComponentIcons.PaginationPrevEllipsisPageIcon, "mdi mdi-dots-horizontal" }, - { ComponentIcons.PaginationNextEllipsisPageIcon, "mdi mdi-dots-horizontal" }, - - { ComponentIcons.PopConfirmButtonConfirmIcon, "mdi mdi-exclamation" }, - - { ComponentIcons.RateStarIcon, "mdi mdi-star" }, - { ComponentIcons.RateUnStarIcon, "mdi mdi-star-outline" }, - - { ComponentIcons.RibbonTabArrowUpIcon, "mdi mdi-chevron-up" }, - { ComponentIcons.RibbonTabArrowDownIcon, "mdi mdi-chevron-down" }, - { ComponentIcons.RibbonTabArrowPinIcon, "mdi mdi-pin mdi-pin-off" }, - - { ComponentIcons.MultiSelectDropdownIcon, "mdi mdi-chevron-up" }, - { ComponentIcons.MultiSelectClearIcon, "mdi mdi-close" }, - - { ComponentIcons.SelectTreeDropdownIcon, "mdi mdi-chevron-up" }, - - { ComponentIcons.SearchClearButtonIcon, "mdi mdi-trash-can-outline" }, - { ComponentIcons.SearchButtonIcon, "mdi mdi-magnify-plus-outline" }, - { ComponentIcons.SearchButtonLoadingIcon, "mdi mdi-loading mdi-spin" }, - - { ComponentIcons.SelectDropdownIcon, "mdi mdi-chevron-up" }, - { ComponentIcons.SelectClearIcon, "mdi mdi-close-circle-outline" }, - { ComponentIcons.SelectSearchIcon, "mdi mdi-magnify-plus-outline" }, - - { ComponentIcons.SweetAlertCloseIcon, "mdi mdi-close" }, - { ComponentIcons.SweetAlertConfirmIcon, "mdi mdi-check" }, - - { ComponentIcons.PrintButtonIcon, "mdi mdi-printer-outline" }, - - { ComponentIcons.ToastSuccessIcon, "mdi mdi-check-circle" }, - { ComponentIcons.ToastInformationIcon, "mdi mdi-alert-circle" }, - { ComponentIcons.ToastWarningIcon, "mdi mdi-alert" }, - { ComponentIcons.ToastErrorIcon, "mdi mdi-close-circle" }, - - { ComponentIcons.TabPreviousIcon, "mdi mdi-chevron-left" }, - { ComponentIcons.TabNextIcon, "mdi mdi-chevron-right" }, - { ComponentIcons.TabDropdownIcon, "mdi mdi-chevron-down" }, - { ComponentIcons.TabCloseIcon, "mdi mdi-close" }, - - { ComponentIcons.TableColumnToolboxIcon, "mdi mdi-cog" }, - - { ComponentIcons.TableSortIconAsc, "mdi mdi-sort-ascending" }, - { ComponentIcons.TableSortDesc, "mdi mdi-sort-descending" }, - { ComponentIcons.TableSortIcon, "mdi mdi-sort" }, - { ComponentIcons.TableFilterIcon, "mdi mdi-filter" }, - { ComponentIcons.TableExportButtonIcon, "mdi mdi-download" }, - - { ComponentIcons.TableAddButtonIcon, "mdi mdi-plus" }, - { ComponentIcons.TableEditButtonIcon, "mdi mdi-file-edit-outline" }, - { ComponentIcons.TableDeleteButtonIcon, "mdi mdi-close" }, - { ComponentIcons.TableRefreshButtonIcon, "mdi mdi-refresh" }, - { ComponentIcons.TableCardViewButtonIcon, "mdi mdi-menu" }, - { ComponentIcons.TableColumnListButtonIcon, "mdi mdi-format-list-bulleted" }, - { ComponentIcons.TableExportCsvIcon, "mdi mdi-file-table-box" }, - { ComponentIcons.TableExportExcelIcon, "mdi mdi-file-excel-box" }, - { ComponentIcons.TableExportPdfIcon, "mdi mdi-file-pdf-box" }, - { ComponentIcons.TableSearchButtonIcon, "mdi mdi-magnify" }, - { ComponentIcons.TableResetSearchButtonIcon, "mdi mdi-trash-can-outline" }, - { ComponentIcons.TableCloseButtonIcon, "mdi mdi-close" }, - { ComponentIcons.TableCancelButtonIcon, "mdi mdi-close" }, - { ComponentIcons.TableSaveButtonIcon, "mdi mdi-content-save" }, - { ComponentIcons.TableAdvanceButtonIcon, "mdi mdi-magnify-plus-outline" }, - { ComponentIcons.TableAdvancedSortButtonIcon, "mdi mdi-sort-alphabetical-descending" }, - - { ComponentIcons.TableTreeIcon, "mdi mdi-menu-right" }, - { ComponentIcons.TableTreeExpandIcon, "mdi mdi-menu-right mdi-rotate-90" }, - { ComponentIcons.TableTreeNodeLoadingIcon, "mdi mdi-loading mdi-spin" }, - { ComponentIcons.TableCopyColumnButtonIcon, "mdi mdi-clipboard-outline" }, - { ComponentIcons.TableGearIcon, "mdi mdi-cog" }, - - { ComponentIcons.TransferLeftIcon, "mdi mdi-chevron-left" }, - { ComponentIcons.TransferRightIcon, "mdi mdi-chevron-right" }, - { ComponentIcons.TransferPanelSearchIcon, "mdi mdi-magnify-plus-outline" }, - - { ComponentIcons.TimerIcon, "mdi mdi-bell-outline" }, - - { ComponentIcons.TreeViewExpandNodeIcon, "mdi mdi-menu-right mdi-rotate-90" }, - { ComponentIcons.TreeViewNodeIcon, "mdi mdi-menu-right" }, - { ComponentIcons.TreeViewSearchIcon, "mdi mdi-magnify" }, - { ComponentIcons.TreeViewResetSearchIcon, "mdi mdi-backspace" }, - - // Upload - { ComponentIcons.AvatarUploadDeleteIcon, "mdi mdi-trash-can-outline" }, - { ComponentIcons.AvatarUploadLoadingIcon, "mdi mdi-loading mdi-spin" }, - { ComponentIcons.AvatarUploadAddIcon, "mdi mdi-plus" }, - { ComponentIcons.AvatarUploadValidStatusIcon, "mdi mdi-check mdi-rotate-315" }, - { ComponentIcons.AvatarUploadInvalidStatusIcon, "mdi mdi-close mdi-rotate-315" }, - - { ComponentIcons.ButtonUploadBrowserButtonIcon, "mdi mdi-folder-open" }, - { ComponentIcons.ButtonUploadLoadingIcon, "mdi mdi-loading mdi-spin" }, - { ComponentIcons.ButtonUploadInvalidStatusIcon, "mdi mdi-close-circle-outline" }, - { ComponentIcons.ButtonUploadValidStatusIcon, "mdi mdi-check-circle-outline" }, - { ComponentIcons.ButtonUploadDeleteIcon, "mdi mdi-trash-can-outline" }, - { ComponentIcons.ButtonUploadDownloadIcon, "mdi mdi-cloud-download-outline" }, - - { ComponentIcons.InputUploadBrowserButtonIcon, "mdi mdi-folder-open" }, - { ComponentIcons.InputUploadDeleteButtonIcon, "mdi mdi-trash-can-outline" }, - - { ComponentIcons.CardUploadAddIcon, "mdi mdi-plus" }, - { ComponentIcons.CardUploadStatusIcon, "mdi mdi-check mdi-rotate-315" }, - { ComponentIcons.CardUploadDeleteIcon, "mdi mdi-close mdi-rotate-315" }, - { ComponentIcons.CardUploadRemoveIcon, "mdi mdi-trash-can-outline" }, - { ComponentIcons.CardUploadDownloadIcon, "mdi mdi-cloud-download-outline" }, - { ComponentIcons.CardUploadZoomIcon, "mdi mdi-magnify-plus-outline" }, - { ComponentIcons.UploadCancelIcon, "mdi mdi-cancel" }, - - { ComponentIcons.FileIconExcel, "mdi mdi-file-excel-outline" }, - { ComponentIcons.FileIconDocx, "mdi mdi-file-word-outline" }, - { ComponentIcons.FileIconPPT, "mdi mdi-file-powerpoint-outline" }, - { ComponentIcons.FileIconAudio, "mdi mdi-file-music-outline" }, - { ComponentIcons.FileIconVideo, "mdi mdi-file-video-outline" }, - { ComponentIcons.FileIconCode, "mdi mdi-file-code-outline" }, - { ComponentIcons.FileIconPdf, "mdi mdi-file-pdf-box" }, - { ComponentIcons.FileIconZip, "mdi mdi-file-cog-outline" }, - { ComponentIcons.FileIconArchive, "mdi mdi-file-document-check-outline" }, - { ComponentIcons.FileIconImage, "mdi mdi-file-image-outline" }, - { ComponentIcons.FileIconFile, "mdi mdi-file-outline" }, - - { ComponentIcons.QueryBuilderPlusIcon, "mdi mdi-plus" }, - { ComponentIcons.QueryBuilderMinusIcon, "mdi mdi-minus" }, - { ComponentIcons.QueryBuilderRemoveIcon, "mdi mdi-close" }, - - { ComponentIcons.ThemeProviderAutoModeIcon, "mdi mdi-circle-half-full" }, - { ComponentIcons.ThemeProviderLightModeIcon, "mdi mdi-white-balance-sunny" }, - { ComponentIcons.ThemeProviderDarkModeIcon, "mdi mdi-weather-night" }, - { ComponentIcons.ThemeProviderActiveModeIcon, "mdi mdi-check" } - }; -} diff --git a/src/components/BootstrapBlazor.MaterialDesign.Extensions/ServiceCollectionExtensions.cs b/src/components/BootstrapBlazor.MaterialDesign.Extensions/ServiceCollectionExtensions.cs deleted file mode 100644 index 161a92f9..00000000 --- a/src/components/BootstrapBlazor.MaterialDesign.Extensions/ServiceCollectionExtensions.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -#if NET8_0_OR_GREATER -using System.Collections.Frozen; -#endif - -using BootstrapBlazor.Components; - -namespace Microsoft.Extensions.DependencyInjection; - -/// -/// BootstrapBlazor 服务扩展类 -/// -public static class IconMapperOptionsExtensions -{ - /// - /// 添加 Material 图标主题服务 - /// - /// - public static IServiceCollection ConfigureMaterialDesignIconTheme(this IServiceCollection services) - { - services.ConfigureIconThemeOptions(options => - { - options.ThemeKey = "mdi"; -#if NET8_0_OR_GREATER - options.TryAddIcons("mdi", DefaultIcon.Icons.ToFrozenDictionary()); -#else - options.Icons["mdi"] = DefaultIcon.Icons; -#endif - }); - return services; - } -} diff --git a/src/components/BootstrapBlazor.OCR/AiForm.razor b/src/components/BootstrapBlazor.OCR/AiForm.razor deleted file mode 100644 index 93a2b06b..00000000 --- a/src/components/BootstrapBlazor.OCR/AiForm.razor +++ /dev/null @@ -1,37 +0,0 @@ -@namespace BootstrapBlazor.Components -@using Microsoft.AspNetCore.Components.Forms - -@if (ShowUI) -{ -
-
- - - - - - -
-} -@if (Debug) -{ -
@log2
-} - -@if (ShowUI) -{ -
- -
- -
- -
- -
- -} diff --git a/src/components/BootstrapBlazor.OCR/AiForm.razor.cs b/src/components/BootstrapBlazor.OCR/AiForm.razor.cs deleted file mode 100644 index d8eeedc2..00000000 --- a/src/components/BootstrapBlazor.OCR/AiForm.razor.cs +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -using Azure.AI.FormRecognizer.DocumentAnalysis; -using BootstrapBlazor.Ocr.Services; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Forms; -using System.Diagnostics.CodeAnalysis; - -namespace BootstrapBlazor.Components; - -/// -/// AI表格识别 AI Form 组件 -/// -public partial class AiForm -{ - public string url { get; set; } = "https://freepos.es/uploads/demo/Doc/ticket.jpg"; - - private string? log; - private string? log2; - [Inject] private AiFormService? AiFormService { get; set; } - - /// - /// 获得/设置 识别完成回调方法,返回 ReadResult - /// - [Parameter] - public Func, Task>? OnReadResult { get; set; } - - /// - /// 获得/设置 识别完成回调方法,返回 string - /// - [Parameter] - public Func, Task>? OnResult { get; set; } - - /// - /// 获得/设置 识别按钮文字 默认为 识别文字 - /// - [Parameter] - [NotNull] - public string? OcrButtonText { get; set; } = "执行识别"; - - - /// - /// 获得/设置 显示内置UI - /// - [Parameter] - public bool ShowUI { get; set; } - - /// - /// 获得/设置 表单识别器模型, 默认为 prebuilt-receipt , 可选值为 prebuilt-read, prebuilt-businessCard, prebuilt-idDocument, prebuilt-invoice, prebuilt-licensePlate, prebuilt-passport, prebuilt-receipt, prebuilt-table, prebuilt-trainTicket, prebuilt-whiteboard, prebuilt-document - /// 参考:https://westus.dev.cognitive.microsoft.com/docs/services/form-recognizer-api-2022-08-31/operations/AnalyzeDocument - /// The ID of the model to use for analyzing the input documents. When using a custom built model - /// for analysis, this parameter must be the ID attributed to the model during its creation. When - /// using one of the service's prebuilt models, one of the supported prebuilt model IDs must be passed. - /// Prebuilt model IDs can be found at . - /// - [Parameter] - public string ModelId { get; set; } = "prebuilt-receipt"; - - /// - /// 获得/设置 显示log - /// - [Parameter] - public bool Debug { get; set; } - - /// - /// 获得/设置 key - /// - [Parameter] - public string? Key { get; set; } - - /// - /// 获得/设置 Endpoint - /// - [Parameter] - public string? Endpoint { get; set; } - - protected string? uploadstatus; - private long maxFileSize = 1024 * 1024 * 15; - public List? Results { get; set; } - protected override async Task OnAfterRenderAsync(bool firstRender) - { - try - { - if (firstRender) - { - if (Key != null) AiFormService!.SubscriptionKey = Key; - if (Endpoint != null) AiFormService!.Endpoint = Endpoint; - AiFormService!.OnResult = OnResult1; - AiFormService.OnStatus = OnStatus; - AiFormService.OnError = OnError1; - } - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - protected async Task OnChange(InputFileChangeEventArgs e) - { - int i = 0; - var selectedFiles = e.GetMultipleFiles(100); - foreach (var item in selectedFiles) - { - i++; - await OnSubmit(item); - uploadstatus += Environment.NewLine + $"[{i}]: " + item.Name; - } - } - - protected async Task OnSubmit(IBrowserFile efile) - { - if (efile == null) return; - try - { - using var stream = efile.OpenReadStream(maxFileSize); - var res = await AiFormService!.AnalyzeDocument(image: stream, modelId: ModelId); - log = ""; - res.ForEach(a => log += a + Environment.NewLine); - StateHasChanged(); - } - catch (Exception e) - { - log += "Error:" + e.Message + Environment.NewLine; - if (OnError != null) await OnError.Invoke(e.Message); - } - StateHasChanged(); - } - private void oninput(ChangeEventArgs e) - { - url = e.Value?.ToString() ?? ""; - } - - /// - /// 识别文字 - /// - public virtual async Task GetOCR() - { - try - { - var res = await AiFormService!.AnalyzeDocument(url, modelId: ModelId); - if (OnResult != null) await OnResult.Invoke(res); - log = ""; - res.ForEach(a => log += a + Environment.NewLine); - StateHasChanged(); - } - catch (Exception e) - { - log += "Error:" + e.Message + Environment.NewLine; - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - /// - /// 获得/设置 错误回调方法 - /// - [Parameter] - public Func? OnError { get; set; } - - private async Task OnResult1(List models) - { - Results = models; - if (OnReadResult != null) await OnReadResult.Invoke(models); - StateHasChanged(); - } - private Task OnStatus(string message) - { - log2 = message; - StateHasChanged(); - return Task.CompletedTask; - } - private Task OnError1(string message) - { - log2 = message; - StateHasChanged(); - return Task.CompletedTask; - } - -} diff --git a/src/components/BootstrapBlazor.OCR/AiForm.razor.css b/src/components/BootstrapBlazor.OCR/AiForm.razor.css deleted file mode 100644 index d32ec8c5..00000000 --- a/src/components/BootstrapBlazor.OCR/AiForm.razor.css +++ /dev/null @@ -1,19 +0,0 @@ - .sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - white-space: nowrap; - border-width: 0; -} - -.input-label { - padding: 20px; - background-color: #f55442; - color: white; - border-radius: 10px; - cursor: pointer; -} \ No newline at end of file diff --git a/src/components/BootstrapBlazor.OCR/AiFormDocumentEmnu.cs b/src/components/BootstrapBlazor.OCR/AiFormDocumentEmnu.cs deleted file mode 100644 index 0ea31225..00000000 --- a/src/components/BootstrapBlazor.OCR/AiFormDocumentEmnu.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -using System.ComponentModel; - -namespace BootstrapBlazor.OCR; - -/// -/// 打印机类型 -/// -public enum AiFormDocumentEmnuType -{ - [Description("prebuilt-read,从文档中提取文本")] - Read, - - [Description("prebuilt-layout,从文档中提取文本和布局信息")] - Layout, - - [Description("prebuilt-document,从文档中提取文本、布局、实体和通用键值对,Key-Value Pairs")] - Document, - - [Description("prebuilt-businessCard,从名片中提取关键信息")] - BusinessCard, - - [Description("prebuilt-idDocument,从护照和身份证中提取关键信息")] - IdDocument, - - [Description("prebuilt-invoice,从发票中提取关键信息,Key-Value Pairs")] - Invoice, - - [Description("prebuilt-receipt,从收据中提取关键信息")] - Receipt, - - [Description("prebuilt-tax.us.w2,从 IRS US W2 税表(2018-2021 年)中提取关键信息")] - Tax_us_w2, - - [Description("prebuilt-vaccinationCard,从美国 Covid-19 CDC 疫苗接种卡中提取关键信息")] - VaccinationCard, - - [Description("prebuilt-healthInsuranceCard.us,从美国健康保险卡中提取关键信息")] - HealthInsuranceCard_us, -} - diff --git a/src/components/BootstrapBlazor.OCR/AzureOpenAI.razor b/src/components/BootstrapBlazor.OCR/AzureOpenAI.razor deleted file mode 100644 index 1e70c504..00000000 --- a/src/components/BootstrapBlazor.OCR/AzureOpenAI.razor +++ /dev/null @@ -1,30 +0,0 @@ -@namespace BootstrapBlazor.Components - -
-
- -
-
- -
-} - -@if (ShowUI_Url) -{ - -
- -
- -
- -} -@if (AnalyzeImage) -{ - -} -@if (AnalyzeImage) -{ - -} -@if (DetectObjects) -{ - -} -@if (DetectDomainSpecific) -{ - -} diff --git a/src/components/BootstrapBlazor.OCR/OCR.razor.cs b/src/components/BootstrapBlazor.OCR/OCR.razor.cs deleted file mode 100644 index c588de16..00000000 --- a/src/components/BootstrapBlazor.OCR/OCR.razor.cs +++ /dev/null @@ -1,349 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -using BootstrapBlazor.Ocr.Services; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Forms; -using Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models; -using System.Diagnostics.CodeAnalysis; - -namespace BootstrapBlazor.Components; - -/// -/// OCR 组件 -/// -public partial class OCR -{ - public string URL { get; set; } = "https://freepos.es/uploads/demo/Doc/libai.jpg"; - - private string? log; - private string? log2; - - [Inject] - [NotNull] - public OcrService? OcrService { get; set; } - - /// - /// 获得/设置 识别完成回调方法,返回 ReadResult - /// - [Parameter] - public Func, Task>? OnReadResult { get; set; } - - /// - /// 获得/设置 识别完成回调方法,返回 string - /// - [Parameter] - public Func, Task>? OnResult { get; set; } - - /// - /// 获得/设置 状态回调方法,返回 string - /// - [Parameter] - public Func? OnStatus { get; set; } - - /// - /// 获得/设置 Url识别按钮文字 默认为 执行识别 - /// - [Parameter] - [NotNull] - public string? OcrUrlButtonText { get; set; } = "执行识别"; - - /// - /// 获得/设置 拍照识别按钮文字 默认为 拍照 - /// - [Parameter] - [NotNull] - public string? OcrCaptureButtonText { get; set; } = "拍照"; - - /// - /// 获得/设置 文件识别按钮文字 默认为 文件 - /// - [Parameter] - [NotNull] - public string? OcrButtonText { get; set; } = "文件"; - - - /// - /// 获得/设置 显示内置UI, 默认为 false - /// - [Parameter] - public bool ShowUI { get; set; } - - /// - /// 获得/设置 显示内置UI, 默认为 true - /// - [Parameter] - public bool ShowUI_Capture { get; set; } = true; - - /// - /// 获得/设置 显示内置识别URL的UI, 默认为 false - /// - [Parameter] - public bool ShowUI_Url { get; set; } - - /// - /// 获得/设置 显示log, 默认为 false - /// - [Parameter] - public bool Debug { get; set; } - - /// - /// 获得/设置 key - /// - [Parameter] - public string? Key { get; set; } - - /// - /// 获得/设置 Endpoint - /// - [Parameter] - public string? Endpoint { get; set; } - - /// - /// 获得/设置 分析图像, 默认为 false - /// - [Parameter] - public bool AnalyzeImage { get; set; } - - /// - /// 获得/设置 检测图像中的对象, 默认为 false - /// - [Parameter] - public bool DetectObjects { get; set; } - - /// - /// 获得/设置 检测图像中的地标或名人, 默认为 false - /// - [Parameter] - public bool DetectDomainSpecific { get; set; } - - protected string? uploadstatus; - private long maxFileSize = 1024 * 1024 * 15; - - public List? Results { get; set; } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - try - { - if (firstRender) - { - if (Key != null) OcrService!.SubscriptionKey = Key; - if (Endpoint != null) OcrService!.Endpoint = Endpoint; - OcrService!.OnResult = OnResult1; - OcrService!.Result = OnResult; - OcrService.OnStatus = OnStatus1; - OcrService.OnError = OnError1; - } - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - protected async Task OnChange(InputFileChangeEventArgs e) - { - int i = 0; - var selectedFiles = e.GetMultipleFiles(100); - foreach (var item in selectedFiles) - { - i++; - await OnSubmit(item); - uploadstatus += Environment.NewLine + $"[{i}]: " + item.Name; - } - } - - protected async Task OnSubmit(IBrowserFile efile) - { - if (efile == null) return; - try - { - using var stream = efile.OpenReadStream(maxFileSize); - await OcrService!.CopyStreamAsync(stream); - if (DetectDomainSpecific || DetectObjects || AnalyzeImage) - { - log = "图像获取成功"; - StateHasChanged(); - return; - } - await OcrGO(); - } - catch (Exception e) - { - log += "Error:" + e.Message + Environment.NewLine; - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - private void oninput(ChangeEventArgs e) - { - URL = e.Value?.ToString() ?? ""; - } - - /// - /// 识别文字 - /// - public virtual async Task GetOCR() => await GetOCR(null); - - /// - /// 识别 url 文字 - /// - public virtual async Task GetOCR(string? url) - { - try - { - var res = await OcrService!.StartOcr(url ?? URL); - if (Debug) - { - log = ""; - res.ForEach(a => log += a + Environment.NewLine); - StateHasChanged(); - } - } - catch (Exception e) - { - log += "Error:" + e.Message + Environment.NewLine; - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - /// - /// 识别 Stream 内的文字 - /// - public virtual async Task OCRFromStream(Stream stream) - { - try - { - var res = await OcrService!.StartOcr(stream: stream); - if (Debug) - { - log = ""; - res.ForEach(a => log += a + Environment.NewLine); - StateHasChanged(); - } - } - catch (Exception e) - { - log += "Error:" + e.Message + Environment.NewLine; - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - /// - /// 获得/设置 错误回调方法 - /// - [Parameter] - public Func? OnError { get; set; } - - - private async Task OnResult1(List models) - { - Results = models; - if (OnReadResult != null) await OnReadResult.Invoke(models); - StateHasChanged(); - } - private async Task OnStatus1(string message) - { - log2 = message; - if (OnStatus != null) await OnStatus.Invoke(message); - StateHasChanged(); - } - - private Task OnStatus2(string message) - { - log += message + Environment.NewLine; - StateHasChanged(); - return Task.CompletedTask; - } - - private Task OnError1(string message) - { - log2 = message; - StateHasChanged(); - return Task.CompletedTask; - } - - - protected async Task OcrGO() - { - if (OcrService.Tempfilename == null) return; - try - { - var res = await OcrService!.OcrLocal(OcrService.Tempfilename); - if (Debug) - { - log = ""; - res.ForEach(a => log += a + Environment.NewLine); - StateHasChanged(); - } - } - catch (Exception e) - { - log += "Error:" + e.Message + Environment.NewLine; - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - protected async Task AnalyzeImageGo() - { - if (OcrService.Tempfilename == null) return; - try - { - var res = await OcrService!.AnalyzeImage(localImage: OcrService.Tempfilename); - if (Debug) - { - log = ""; - res.ForEach(a => log += a + Environment.NewLine); - StateHasChanged(); - } - } - catch (Exception e) - { - log += "Error:" + e.Message + Environment.NewLine; - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - protected async Task DetectObjectsGO() - { - if (OcrService.Tempfilename == null) return; - try - { - var res = await OcrService!.DetectObjects(localImage: OcrService.Tempfilename); - if (Debug) - { - log = ""; - res.ForEach(a => log += a + Environment.NewLine); - StateHasChanged(); - } - } - catch (Exception e) - { - log += "Error:" + e.Message + Environment.NewLine; - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - protected async Task DetectDomainSpecificGo() - { - if (OcrService.Tempfilename == null) return; - try - { - var res = await OcrService!.DetectDomainSpecific(localImage: OcrService.Tempfilename); - if (Debug) - { - log = ""; - res.ForEach(a => log += a + Environment.NewLine); - StateHasChanged(); - } - } - catch (Exception e) - { - log += "Error:" + e.Message + Environment.NewLine; - if (OnError != null) await OnError.Invoke(e.Message); - } - } - -} diff --git a/src/components/BootstrapBlazor.OCR/OCR.razor.css b/src/components/BootstrapBlazor.OCR/OCR.razor.css deleted file mode 100644 index 2b40c84f..00000000 --- a/src/components/BootstrapBlazor.OCR/OCR.razor.css +++ /dev/null @@ -1,19 +0,0 @@ -.sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - white-space: nowrap; - border-width: 0; -} - -.input-label { - padding: 20px; - background-color: #f55442; - color: white; - border-radius: 10px; - cursor: pointer; -} diff --git a/src/components/BootstrapBlazor.OCR/PlayAudio.razor b/src/components/BootstrapBlazor.OCR/PlayAudio.razor deleted file mode 100644 index 575713d7..00000000 --- a/src/components/BootstrapBlazor.OCR/PlayAudio.razor +++ /dev/null @@ -1,9 +0,0 @@ -@namespace BootstrapBlazor.Components - -
- -@if (!string.IsNullOrEmpty(ErrorMessage)) -{ -

@ErrorMessage

-} - diff --git a/src/components/BootstrapBlazor.OCR/PlayAudio.razor.cs b/src/components/BootstrapBlazor.OCR/PlayAudio.razor.cs deleted file mode 100644 index 11062b3a..00000000 --- a/src/components/BootstrapBlazor.OCR/PlayAudio.razor.cs +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - - -using BootstrapBlazor.AzureServices; -using Microsoft.AspNetCore.Components; -using Microsoft.Extensions.Configuration; -using Microsoft.JSInterop; -using System.Diagnostics.CodeAnalysis; - -namespace BootstrapBlazor.Components; - -/// -/// PlayAudio 播放语音/文本转语音 组件 -/// -public partial class PlayAudio : IAsyncDisposable -{ - [Inject] - [NotNull] - private IJSRuntime? JSRuntime { get; set; } - - [Inject] - [NotNull] - private StsService? StsService { get; set; } - - [NotNull] - private IJSObjectReference? Module { get; set; } - - /// - /// UI界面元素的引用对象 - /// - private ElementReference Element { get; set; } - - /// - /// 语音名称, 默认 zh-HK-HiuGaaiNeural - /// - [Parameter] - public string VoiceName { get; set; } = "zh-HK-HiuGaaiNeural"; - - /// - /// 语音风格, 默认 calm - /// - [Parameter] - public string Style { get; set; } = "calm"; - - /// - /// 文本/SSML内容 - /// - [Parameter] - public string? TextOrSSML { get; set; } - - /// - /// 数据流, 优先级高于 TextOrSSML - /// - [Parameter] - public byte[]? Bytes { get; set; } - - [NotNull] - [Inject] - private IConfiguration? Config { get; set; } - - private string? ErrorMessage { get; set; } - - public bool Processing = false; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - Module = await JSRuntime.InvokeAsync("import", "./_content/BootstrapBlazor.OCR/audio.js" + "?v=" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version); - await Task.Delay(100); - await Play(); - } - } - - public async Task Play() - { - if (Bytes != null) - { - await PlayAudioFileStream(Bytes); - } - else if (!string.IsNullOrEmpty(TextOrSSML)) - { - await PlayAudioFromText(); - } - } - - /// - /// 播放数据流 - /// - /// - /// - - public async Task Play(byte[] bytes) - { - if (Module == null) - { - Bytes = bytes; - } - else - { - await PlayAudioFileStream(bytes); - } - } - - /// - /// 播放文本 - /// - /// - /// - /// - /// - public async Task Play(string textOrSSML, string? voicename = null, string? style = null) - { - TextOrSSML = textOrSSML; - VoiceName = voicename ?? VoiceName; - Style = style ?? Style; - - if (Module != null) - { - await PlayAudioFromText(); - } - - } - - private async Task PlayAudioFileStream(byte[]? bytes) - { - if (bytes != null) - { - var stream = new MemoryStream(bytes); - using var streamRef = new DotNetStreamReference(stream: stream); - // 播放音频文件 - await Module.InvokeVoidAsync("PlayAudioFileStream", streamRef, Element); - } - else - { - ErrorMessage = "Error creating audio file."; - } - Processing = false; - StateHasChanged(); - } - - private async Task PlayAudioFromText() - { - if (string.IsNullOrWhiteSpace(TextOrSSML)) - { - return; - } - - StateHasChanged(); - Processing = true; - // 获取音频文件的字节流 - var bytes = await StsService.GetVoiceAsync(TextOrSSML, VoiceName, Style); - await PlayAudioFileStream(bytes); - } - - /// - /// - /// - /// - public async ValueTask DisposeAsync() - { - if (Module is not null) - { - await Module.DisposeAsync(); - } - GC.SuppressFinalize(this); - } - - -} diff --git a/src/components/BootstrapBlazor.OCR/Services/AiFormService.cs b/src/components/BootstrapBlazor.OCR/Services/AiFormService.cs deleted file mode 100644 index 4ed88797..00000000 --- a/src/components/BootstrapBlazor.OCR/Services/AiFormService.cs +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -using Azure; -using Azure.AI.FormRecognizer.DocumentAnalysis; -using BootstrapBlazor.OCR; -using BootstrapBlazor.OCR.Services; -using Microsoft.Extensions.Configuration; - -namespace BootstrapBlazor.Ocr.Services; - -/// -/// AI Form 表格识别 -/// -public class AiFormService : BaseService -{ - - /* - 此代码示例显示使用 Azure 表单识别器客户端库进行的预构建收据操作。 - 要了解更多信息,请访问文档 - 快速入门:表单识别器 C# 客户端库 SDK - https://docs.microsoft.com/en-us/azure/applied-ai-services/form-recognizer/quickstarts/try-v3-csharp-sdk - */ - - - /* - 完成后请记住从您的代码中删除密钥,并且永远不要公开发布。对于生产,使用 - 存储和访问您的凭据的安全方法。有关详细信息,请参阅 - https://docs.microsoft.com/en-us/azure/cognitive-services/cognitive-services-security?tabs=command-line%2Ccsharp#environment-variables-and-application-configuration - */ - - public string Endpoint = "YOUR_FORM_RECOGNIZER_ENDPOINT"; - - public string SubscriptionKey = "YOUR_FORM_RECOGNIZER_KEY"; - - public AiFormService(IConfiguration? config) - { - if (config != null) - { - SubscriptionKey = config["AzureCvKey"] ?? ""; - Endpoint = config["AzureCvUrl"] ?? ""; - } - } - - public AiFormService(string key, string url) - { - SubscriptionKey = key; - Endpoint = url; - } - - - public async Task> AnalyzeDocument(string? url = null, Stream? image = null, string modelId = "prebuilt-receipt") - { - msg = "AnalyzeDocument start "; - await GetStatus(msg); - - var credential = new AzureKeyCredential(SubscriptionKey); - var client = new DocumentAnalysisClient(new Uri(Endpoint), credential); - - - AnalyzeDocumentOperation operation; - - if (image != null) - { - var ms = await Utils.CopyStream(image); - operation = await client.AnalyzeDocumentAsync(WaitUntil.Completed, modelId, ms); - } - else - { - //sample document - Uri receiptUri = new Uri(url ?? "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/main/sdk/formrecognizer/azure-ai-formrecognizer/tests/sample_forms/receipt/contoso-receipt.png"); - operation = await client.AnalyzeDocumentFromUriAsync(WaitUntil.Completed, modelId, receiptUri); - } - - AnalyzeResult receipts = operation.Value; - - // To see the list of the supported fields returned by service and its corresponding types, consult: - // https://aka.ms/formrecognizer/receiptfields - - await GetResult(receipts.Documents.ToList()); - var res = new List(); - foreach (AnalyzedDocument receipt in receipts.Documents) - { - if (receipt.Fields.TryGetValue("MerchantName", out DocumentField? merchantNameField)) - { - if (merchantNameField.FieldType == DocumentFieldType.String) - { - string merchantName = merchantNameField.Value.AsString(); - - msg = $"Merchant Name: '{merchantName}', with confidence {merchantNameField.Confidence}"; - await GetStatus(msg); - res.Add(msg); - - } - } - - if (receipt.Fields.TryGetValue("TransactionDate", out DocumentField? transactionDateField)) - { - if (transactionDateField.FieldType == DocumentFieldType.Date) - { - DateTimeOffset transactionDate = transactionDateField.Value.AsDate(); - - msg = $"Transaction Date: '{transactionDate}', with confidence {transactionDateField.Confidence}"; - await GetStatus(msg); - res.Add(msg); - - } - } - - if (receipt.Fields.TryGetValue("Items", out DocumentField? itemsField)) - { - if (itemsField.FieldType == DocumentFieldType.List) - { - foreach (DocumentField itemField in itemsField.Value.AsList()) - { - msg = "Item:"; - await GetStatus(msg); - res.Add(msg); - - if (itemField.FieldType == DocumentFieldType.Dictionary) - { - IReadOnlyDictionary itemFields = itemField.Value.AsDictionary(); - - if (itemFields.TryGetValue("Description", out DocumentField? itemDescriptionField)) - { - if (itemDescriptionField.FieldType == DocumentFieldType.String) - { - string itemDescription = itemDescriptionField.Value.AsString(); - - msg = $" Description: '{itemDescription}', with confidence {itemDescriptionField.Confidence}"; - await GetStatus(msg); - res.Add(msg); - - } - } - - if (itemFields.TryGetValue("TotalPrice", out DocumentField? itemTotalPriceField)) - { - if (itemTotalPriceField.FieldType == DocumentFieldType.Double) - { - double itemTotalPrice = itemTotalPriceField.Value.AsDouble(); - - msg = $" Total Price: '{itemTotalPrice}', with confidence {itemTotalPriceField.Confidence}"; - await GetStatus(msg); - res.Add(msg); - - } - } - } - } - } - } - - if (receipt.Fields.TryGetValue("Total", out DocumentField? totalField)) - { - if (totalField.FieldType == DocumentFieldType.Double) - { - double total = totalField.Value.AsDouble(); - - msg = $"Total: '{total}', with confidence '{totalField.Confidence}'"; - await GetStatus(msg); - res.Add(msg); - - } - } - } - return res; - } -} - diff --git a/src/components/BootstrapBlazor.OCR/Services/AiFormServiceCollectionExtensions.cs b/src/components/BootstrapBlazor.OCR/Services/AiFormServiceCollectionExtensions.cs deleted file mode 100644 index ecbbdad1..00000000 --- a/src/components/BootstrapBlazor.OCR/Services/AiFormServiceCollectionExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -using BootstrapBlazor.Ocr.Services; - -namespace Microsoft.Extensions.DependencyInjection; - -/// -/// AI Form 服务扩展类 -/// -public static class AiFormServiceCollectionExtensions -{ - - /// - /// 增加 AI Form 服务扩展类, - /// - /// - /// - /// - /// - public static IServiceCollection AddAIFormExtensions(this IServiceCollection services, string? key = null, string? url = null) - { - if (key != null && url != null) services.AddTransient(sp => new AiFormService(key, url)); - else services.AddTransient(); - return services; - } - -} diff --git a/src/components/BootstrapBlazor.OCR/Services/BaseService.cs b/src/components/BootstrapBlazor.OCR/Services/BaseService.cs deleted file mode 100644 index 467bf34b..00000000 --- a/src/components/BootstrapBlazor.OCR/Services/BaseService.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -using Console = System.Console; - -namespace BootstrapBlazor.OCR.Services; - -public class BaseService -{ - - /// - /// 获得/设置 识别完成回调方法,返回 Model 集合 - /// - public Func, Task>? OnResult { get; set; } - - /// - /// 获得/设置 状态回调方法 - /// - public Func? OnStatus { get; set; } - - /// - /// 获得/设置 错误回调方法 - /// - public Func? OnError { get; set; } - - public async Task GetStatus(string status = "----------------------------------------------------------") - { - try - { - Console.WriteLine(status); - if (OnStatus != null) await OnStatus.Invoke(status); - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - return status; - } - - public async Task GetResult(List models) - { - try - { - Console.WriteLine(models); - if (OnResult != null) await OnResult.Invoke(models); - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - public string? msg = string.Empty; - -} diff --git a/src/components/BootstrapBlazor.OCR/Services/OcrService.cs b/src/components/BootstrapBlazor.OCR/Services/OcrService.cs deleted file mode 100644 index 853b42ef..00000000 --- a/src/components/BootstrapBlazor.OCR/Services/OcrService.cs +++ /dev/null @@ -1,299 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -using BootstrapBlazor.OCR.Services; -using Microsoft.Azure.CognitiveServices.Vision.ComputerVision; -using Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models; -using Microsoft.Extensions.Configuration; -using Console = System.Console; - -namespace BootstrapBlazor.Ocr.Services; - -/// -/// OCR -/// -public partial class OcrService : BaseService -{ - public string? LocalFilePath; - - //https://learn.microsoft.com/zh-cn/azure/cognitive-services/computer-vision/quickstarts-sdk/client-library?tabs=visual-studio&pivots=programming-language-csharp - // 添加您的计算机视觉订阅密钥和端点 - - public string SubscriptionKey = "your Computer Vision subscription key"; - - public string Endpoint = "https://xxx.cognitiveservices.azure.com/"; - - //public Stream? Stream { get; set; } - public string? Tempfilename { get; set; } - - /// - /// 获得/设置 识别完成回调方法,结果为string集合 - /// - public Func, Task>? Result { get; set; } - - public OcrService(IConfiguration? config) - { - if (config != null) - { - SubscriptionKey = config["AzureCvKey"] ?? ""; - Endpoint = config["AzureCvUrl"] ?? ""; - } - } - - public OcrService(string localFilePath) - { - LocalFilePath = localFilePath; - } - - public OcrService(string key, string url, string localFilePath) - { - LocalFilePath = localFilePath; - SubscriptionKey = key; - Endpoint = url; - } - - private ComputerVisionClient? client_; - - public ComputerVisionClient Client - { - get => client_ = client_ ?? Authenticate(Endpoint, SubscriptionKey); - set => client_ = value; - } - - /// - /// 转换和提取结果 - /// - /// - /// - private async Task GetResult(List models) - { - try - { - Console.WriteLine(models); - if (Result != null) await Result.Invoke(models); - } - catch (Exception e) - { - if (OnError != null) await OnError.Invoke(e.Message); - } - } - - /// - /// 从图像中提取文本 (OCR) - /// - /// - /// - /// - public async Task> StartOcr(string? url = null, Stream? stream = null) - { - msg = "Ocr start"; - await GetStatus(msg); - Console.WriteLine(); - Tempfilename = null; - - if (stream != null) - { -#if (IOS || MACCATALYST) - var ms = await CopyStream(stream); - var res1 = await ReadFileLocal(url ?? "", ms); -#else - if (LocalFilePath != null) - { - Tempfilename = Path.Combine(LocalFilePath, "temp.jpg"); - await using FileStream fs = new(Tempfilename, FileMode.Create); - await stream.CopyToAsync(fs); - var res1 = await OcrLocal(Tempfilename); - return res1; - - } - else - { - var res1 = await OcrLocal(url ?? "", stream); - return res1; - } - -#endif - - } - else - { - // 使用读取 API 从 URL 图像中提取文本 (OCR) - var res = await OcrUrl(url ?? ""); - return res; - - } - - } - - - - /// - /// 暂存图片流 - /// - /// - /// - public async Task CopyStreamAsync(Stream stream) - { - msg = "Save a stream"; - await GetStatus(msg); - try - { - Tempfilename = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); - await using FileStream fs = new(Tempfilename, FileMode.Create); - await stream.CopyToAsync(fs); - } - catch - { - Tempfilename = null; - } - } - - /// - /// 初始化 ComputerVisionClient 类的新实例 - /// - /// - /// - /// - public ComputerVisionClient Authenticate(string endpoint, string key) - { - ComputerVisionClient client = new ComputerVisionClient(new ApiKeyServiceClientCredentials(key)) { Endpoint = endpoint }; - return client; - } - - /// - /// 从 URL 提取文本 - /// - /// - /// - public async Task> OcrUrl(string urlFile) - { - Console.WriteLine("----------------------------------------------------------"); - msg = "从 URL 提取文本"; - await GetStatus(msg); - Console.WriteLine(); - - // 从 URL 读取文本 - var textHeaders = await Client.ReadAsync(urlFile); - // 请求后,获取操作位置(操作ID) - string operationLocation = textHeaders.OperationLocation; - Thread.Sleep(2000); - - // 从 Operation-Location 标头中检索将存储提取的文本的 URI。 - // 我们只需要 ID 而不是完整的 URL - const int numberOfCharsInOperationId = 36; - string operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId); - - // 提取文本 - ReadOperationResult results; - msg = $"从 URL 文件中提取文本 {Path.GetFileName(urlFile)}..."; - await GetStatus(msg); - Console.WriteLine(); - do - { - results = await Client.GetReadResultAsync(Guid.Parse(operationId)); - msg = $"{results.Status}..."; - await GetStatus(msg); - } - while ((results.Status is OperationStatusCodes.Running or - OperationStatusCodes.NotStarted)); - - // 显示找到的文本。 - Console.WriteLine(); - var res = new List(); - var textUrlFileResults = results.AnalyzeResult.ReadResults; - await GetStatus("end"); - await GetResult(textUrlFileResults.ToList()); - foreach (ReadResult page in textUrlFileResults) - { - foreach (Line line in page.Lines) - { - res.Add($"{line.Text}"); - Console.WriteLine($"{line.Text}"); - } - } - Console.WriteLine(); - await GetResult(res); - return res; - - } - - - /// - /// 从本地文件或者流提取文本 - /// - /// - /// - /// - /// - public async Task> OcrLocal(string localFile, Stream? stream = null, bool splitPerLine = false) - { - Console.WriteLine("----------------------------------------------------------"); - msg = stream != null ? "从流提取文本" : "从本地文件提取文本"; - await GetStatus(msg); - Console.WriteLine(); - - // 从 URL 读取文本 - var textHeaders = await Client.ReadInStreamAsync(stream ?? File.OpenRead(localFile)); - // 请求后,获取操作位置(操作 operation ID) - string operationLocation = textHeaders.OperationLocation; - Thread.Sleep(2000); - - // - // 从 Operation-Location 标头中检索将存储已识别文本的 URI。 - // 我们只需要 ID 而不是完整的 URL - const int numberOfCharsInOperationId = 36; - string operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId); - - // 提取文本 - ReadOperationResult results; - msg = stream != null ? "从流提取文本" : $"从文件 {Path.GetFileName(localFile)} 提取文本..."; - await GetStatus(msg); - Console.WriteLine(); - do - { - results = await Client.GetReadResultAsync(Guid.Parse(operationId)); - } - while ((results.Status is OperationStatusCodes.Running or - OperationStatusCodes.NotStarted)); - // - - // - // 显示找到的文本。 - Console.WriteLine(); - var res = new List(); - var res2 = new List(); - double? lastheight = 0.0; - var textUrlFileResults = results.AnalyzeResult.ReadResults; - await GetStatus("end"); - await GetResult(textUrlFileResults.ToList()); - foreach (ReadResult page in textUrlFileResults) - { - Console.WriteLine($"Angle角度: {page.Angle}"); - var line2 = ""; - foreach (Line line in page.Lines) - { - res.Add($"{line.Text}"); - if (line.BoundingBox[1] >= lastheight + 20 || line.BoundingBox[1] <= lastheight - 20) - { - //X 左上、Y 左上、 X 右上、Y 右上、 X 右下、Y 右下、 X 左下、Y 左下 - line2 += line.Text + "\t"; - } - else - { - Console.WriteLine($"line2=> {line2}"); - res2.Add(line2); - line2 = ""; - } - lastheight = line.BoundingBox[1]; - Console.WriteLine($"{line.Text} Y 左上{line.BoundingBox[1]}"); - } - } - Console.WriteLine(); - await GetResult(res); - return res; - } - - -} - diff --git a/src/components/BootstrapBlazor.OCR/Services/OcrServiceAdv.cs b/src/components/BootstrapBlazor.OCR/Services/OcrServiceAdv.cs deleted file mode 100644 index bf6dcee8..00000000 --- a/src/components/BootstrapBlazor.OCR/Services/OcrServiceAdv.cs +++ /dev/null @@ -1,365 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -using BootstrapBlazor.OCR.Services; -using Microsoft.Azure.CognitiveServices.Vision.ComputerVision; -using Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace BootstrapBlazor.Ocr.Services; - -/// -/// OCR -/// -public partial class OcrService : BaseService -{ - #region 分析图像 - // 创建一个列表,定义要从图像中提取的特征。 - public List Features = new List() - { - VisualFeatureTypes.Categories, VisualFeatureTypes.Description, - VisualFeatureTypes.Faces, VisualFeatureTypes.ImageType, - VisualFeatureTypes.Tags, VisualFeatureTypes.Adult, - VisualFeatureTypes.Color, VisualFeatureTypes.Brands, - VisualFeatureTypes.Objects - }; - - /// - /// 分析图像 - /// 分析图像以获得特征和其他属性 - ///分析 URL 图片。提取标题、类别、标签、对象、面孔、色情/成人/血腥内容, - ///品牌、名人、地标、配色方案和图像类型。 - /// - /// URL - /// 流 - /// 本地图片文件 - /// - public async Task> AnalyzeImage(string? urlImage = null, Stream? stream = null, string? localImage = null) - { - await GetStatus($"分析图像 - {Desc(urlImage, stream, localImage)}..."); - - if (stream == null && !string.IsNullOrEmpty(localImage)) - { - // 检测本地图像中特定于域的内容。 - stream = File.OpenRead(localImage); - } - //分析 URL 图片 - ImageAnalysis results = (stream == null) ? await Client.AnalyzeImageAsync(urlImage, visualFeatures: Features) : await Client.AnalyzeImageInStreamAsync(stream, visualFeatures: Features); - - var res = await AnalyzeResults(results); - - return res; - } - - /// - /// 分析图像 - /// - /// - /// - public async Task> AnalyzeResults(ImageAnalysis results) - { - var res = new List(); - - // 对图像内容进行概述。 - if (null != results.Description && null != results.Description.Captions) - { - res.Add(await GetStatus("概括:")); - foreach (var caption in results.Description.Captions) - { - res.Add(await GetStatus($"{caption.Text} 可信度 {caption.Confidence:P2}")); - } - res.Add(await GetStatus()); - } - - // 显示图像被划分的类别。 - if (null != results.Categories) - { - res.Add(await GetStatus("类别:")); - foreach (var category in results.Categories) - { - res.Add(await GetStatus($"{category.Name} 可信度 {category.Score:P2}")); - } - res.Add(await GetStatus()); - } - - // 图像标签及其置信度得分 - if (null != results.Tags) - { - res.Add(await GetStatus("标签:")); - foreach (var tag in results.Tags) - { - res.Add(await GetStatus($"{tag.Name} 可信度 {tag.Confidence:P2}")); - } - res.Add(await GetStatus()); - } - - // 对象 - if (null != results.Objects) - { - res.Add(await GetStatus("对象:")); - foreach (var obj in results.Objects) - { - res.Add(await GetStatus($"{obj.ObjectProperty} 可信度 {obj.Confidence:P2} 位置 {obj.Rectangle.X}, " + - $"{obj.Rectangle.X + obj.Rectangle.W}, {obj.Rectangle.Y}, {obj.Rectangle.Y + obj.Rectangle.H}")); - } - res.Add(await GetStatus()); - } - - // 面孔 - if (null != results.Faces) - { - - res.Add(await GetStatus("面孔:")); - foreach (var face in results.Faces) - { - res.Add(await GetStatus($"面孔 {face.Gender} 年龄 {face.Age} 位置 {face.FaceRectangle.Left}, " + - $"{face.FaceRectangle.Left}, {face.FaceRectangle.Top + face.FaceRectangle.Width}, " + - $"{face.FaceRectangle.Top + face.FaceRectangle.Height}")); - } - res.Add(await GetStatus()); - } - - // 成人或不雅内容 - if (null != results.Adult) - { - - res.Add(await GetStatus("成人或不雅内容:")); - - if (results.Adult.IsAdultContent) - res.Add(await GetStatus($"有成人内容: {results.Adult.IsAdultContent} 可信度 {results.Adult.AdultScore:P2}")); - - if (results.Adult.IsRacyContent) - res.Add(await GetStatus($"有不雅内容: {results.Adult.IsRacyContent} 可信度 {results.Adult.RacyScore:P2}")); - - if (results.Adult.IsGoryContent) - res.Add(await GetStatus($"有血腥内容: {results.Adult.IsGoryContent} 可信度 {results.Adult.GoreScore:P2}")); - - res.Add(await GetStatus()); - } - - // 知名品牌 - if (null != results.Brands) - { - res.Add(await GetStatus("知名品牌:")); - foreach (var brand in results.Brands) - { - res.Add(await GetStatus($"商标 {brand.Name} 可信度 {brand.Confidence:P2} 位置 {brand.Rectangle.X}, " + - $"{brand.Rectangle.X + brand.Rectangle.W}, {brand.Rectangle.Y}, {brand.Rectangle.Y + brand.Rectangle.H}")); - } - res.Add(await GetStatus()); - } - - // 名人形象 - if (null != results.Categories) - { - res.Add(await GetStatus("名人:")); - foreach (var category in results.Categories) - { - if (category.Detail?.Celebrities != null) - { - foreach (var celeb in category.Detail.Celebrities) - { - res.Add(await GetStatus($"{celeb.Name} 可信度 {celeb.Confidence:P2} 位置 {celeb.FaceRectangle.Left}, " + - $"{celeb.FaceRectangle.Top}, {celeb.FaceRectangle.Height}, {celeb.FaceRectangle.Width}")); - } - } - } - res.Add(await GetStatus()); - } - - // 图像中的热门地标(如果有)。 - if (null != results.Categories) - { - res.Add(await GetStatus("地标:")); - foreach (var category in results.Categories) - { - if (category.Detail?.Landmarks != null) - { - foreach (var landmark in category.Detail.Landmarks) - { - res.Add(await GetStatus($"{landmark.Name} 可信度 {landmark.Confidence:P2}")); - } - } - } - res.Add(await GetStatus()); - } - - //标识配色方案。 - if (null != results.Color) - { - res.Add(await GetStatus("配色方案:")); - res.Add(await GetStatus("是黑白照片: " + results.Color.IsBWImg)); - res.Add(await GetStatus("强调色: " + results.Color.AccentColor)); - res.Add(await GetStatus("主背景色: " + results.Color.DominantColorBackground)); - res.Add(await GetStatus("主前景颜色: " + results.Color.DominantColorForeground)); - res.Add(await GetStatus("主色调: " + string.Join(",", results.Color.DominantColors))); - res.Add(await GetStatus()); - } - - // 检测图像类型。 - if (null != results.ImageType) - { - res.Add(await GetStatus("图像类型:")); - res.Add(await GetStatus("剪贴画类型: " + results.ImageType.ClipArtType)); - res.Add(await GetStatus("画线类型: " + results.ImageType.LineDrawingType)); - res.Add(await GetStatus()); - } - - return res; - - } - - #endregion - - /// - /// 检测图像中的对象 - 本地图像 - /// 这是检测对象的替代方法,而不是通过分析图像进行检测. - /// - /// URL - /// 流 - /// 本地图片文件 - /// - public async Task> DetectObjects(string? urlImage = null, Stream? stream = null, string? localImage = null) - { - var res = new List - { - await GetStatus("----------------------------------------------------------"), - await GetStatus($"检测对象 - {Desc(urlImage, stream, localImage)}"), - await GetStatus() - }; - - if (stream == null && !string.IsNullOrEmpty(localImage)) - { - // 检测本地图像中特定于域的内容。 - stream = File.OpenRead(localImage); - } - - // 使用本地文件调用计算机视觉服务 - DetectResult results = (stream == null) ? await Client.DetectObjectsAsync(urlImage) : await Client.DetectObjectsInStreamAsync(stream); - - res.Add(await GetStatus($"检测图像中的物体 {Path.GetFileName(localImage)}...")); - res.Add(await GetStatus()); - - // 对于图片中的每个检测到的对象,打印出检测到的边界对象、该检测的置信度和图像中的边界框 - res.Add(await GetStatus("检测对象:")); - foreach (var obj in results.Objects) - { - res.Add(await GetStatus($"{obj.ObjectProperty} 可信度 {obj.Confidence:P2} 位置 {obj.Rectangle.X}, " + - $"{obj.Rectangle.X + obj.Rectangle.W}, {obj.Rectangle.Y}, {obj.Rectangle.Y + obj.Rectangle.H}")); - } - res.Add(await GetStatus()); - - return res; - } - - /// - /// 检测 URL 图像中的地标或名人 - /// 检测特定领域的内容 - /// 识别图像中的地标或名人。 - /// - /// URL - /// 流 - /// 本地图片文件 - /// - public async Task> DetectDomainSpecific(string? urlImage = null, Stream? stream = null, string? localImage = null) - { - var res = new List - { - await GetStatus("----------------------------------------------------------"), - await GetStatus($"检测域特定内容 - {Desc(urlImage, stream, localImage)}"), - await GetStatus() - }; - - if (!string.IsNullOrEmpty(urlImage)) - { - // 检测 URL 图像中特定于域的内容。 - DomainModelResults resultsUrl = await Client.AnalyzeImageByDomainAsync("landmarks", urlImage); - // 显示结果。 - var jsonUrl = JsonConvert.SerializeObject(resultsUrl.Result); - JObject resultJsonUrl = JObject.Parse(jsonUrl); - if (resultJsonUrl["landmarks"]!.Any()) - { - res.Add(await GetStatus($"检测到地标: {resultJsonUrl["landmarks"][0]["name"]} " + - $"可信度 {resultJsonUrl["landmarks"][0]["confidence"]:P2}.")); - } - res.Add(await GetStatus()); - } - - if (stream == null && !string.IsNullOrEmpty(localImage)) - { - // 检测本地图像中特定于域的内容。 - stream = File.OpenRead(localImage); - } - - if (stream != null) - { - try - { - // 如果您感兴趣,请将“名人”更改为“地标”。 - DomainModelResults resultsLocal = await Client.AnalyzeImageByDomainInStreamAsync("celebrities", stream); - res.Add(await GetStatus($"在本地图像中检测名人 {Path.GetFileName(localImage)}...")); - // 显示结果。 - var jsonLocal = JsonConvert.SerializeObject(resultsLocal.Result); - JObject resultJsonLocal = JObject.Parse(jsonLocal); - if (resultJsonLocal["celebrities"]!.Any()) - { - res.Add(await GetStatus($"检测到名人: {resultJsonLocal["celebrities"][0]["name"]} " + - $"可信度 {resultJsonLocal["celebrities"][0]["confidence"]:P2}")); - } - } - catch (Exception e) - { - res.Add(await GetStatus($"检测名人出错: {e.Message}")); - } - res.Add(await GetStatus()); - } - - return res; - } - - /// - /// 从 URL 和本地图像生成缩略图 - /// 接受 URL 和本地图像,此示例将生成具有指定宽度/高度(像素)的缩略图。 - /// 缩略图将保存在本地。 - /// - /// URL - /// 流 - /// 本地图片文件 - /// - public async Task> GenerateThumbnail(string? urlImage = null, Stream? stream = null, string? localImage = null) - { - var res = new List - { - await GetStatus("----------------------------------------------------------"), - await GetStatus($"生成缩略图 - {Desc(urlImage, stream, localImage)}"), - await GetStatus() - }; - if (stream == null && !string.IsNullOrEmpty(localImage)) - { - // 检测本地图像中特定于域的内容。 - stream = File.OpenRead(localImage); - } - - // 缩略图将本地保存在此项目的 bin\Debug\netcoreappx.x\ 文件夹中。 - string localSavePath = @"."; - - // 将 smart Cropping 设置为 true 可使图像调整其纵横比 - // 以图像中感兴趣的区域为中心。如果需要,更改宽度/高度。 - Stream thumbnailUrl = (stream == null) ? await Client.GenerateThumbnailAsync(60, 60, urlImage, true) : await Client.GenerateThumbnailInStreamAsync(100, 100, stream, smartCropping: true); - - string imageNameUrl = Path.GetFileName(urlImage ?? "temp.jpg"); - string thumbnailFilePathUrl = Path.Combine(localSavePath, imageNameUrl.Insert(imageNameUrl.Length - 4, "_thumb")); - - res.Add(await GetStatus("将缩略图从 URL 图像保存到 " + thumbnailFilePathUrl)); - using (Stream file = File.Create(thumbnailFilePathUrl)) { thumbnailUrl.CopyTo(file); } - - res.Add(await GetStatus()); - - return res; - } - - private string Desc(string? urlImage, Stream? stream, string? localImage) => urlImage != null ? Path.GetFileName(urlImage) : (stream != null ? "文件流" : localImage ?? ""); -} - diff --git a/src/components/BootstrapBlazor.OCR/Services/OcrServiceCollectionExtensions.cs b/src/components/BootstrapBlazor.OCR/Services/OcrServiceCollectionExtensions.cs deleted file mode 100644 index e8bc0d85..00000000 --- a/src/components/BootstrapBlazor.OCR/Services/OcrServiceCollectionExtensions.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -using BootstrapBlazor.Ocr.Services; - -namespace Microsoft.Extensions.DependencyInjection; - -/// -/// OCR 服务扩展类 -/// -public static class OcrServiceCollectionExtensions -{ - - /// - /// 增加 OCR 服务扩展类, - /// - /// - /// - /// - /// - /// - public static IServiceCollection AddOcrExtensions(this IServiceCollection services, string? key = null, string? url = null, string? localFilePath = null) - { - if (key != null && url != null) services.AddTransient(sp => new OcrService(key, url, localFilePath)); - else if (localFilePath != null) services.AddTransient(sp => new OcrService(localFilePath)); - else services.AddTransient(); - return services; - } - -} diff --git a/src/components/BootstrapBlazor.OCR/Services/OpenAIClientService.cs b/src/components/BootstrapBlazor.OCR/Services/OpenAIClientService.cs deleted file mode 100644 index abf1cdf1..00000000 --- a/src/components/BootstrapBlazor.OCR/Services/OpenAIClientService.cs +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -#if NET7_0_OR_GREATER -using AzureOpenAIClient.Http; -using Microsoft.Extensions.Configuration; -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Console = System.Console; - -namespace BootstrapBlazor.AzureServices; - -public class AzureOpenAIService -{ - //public string SubscriptionKey = "your Computer Vision subscription key"; - - //public string Endpoint = "https://api.cognitive.microsofttranslator.com"; - - [NotNull] - private OpenAIClient? _openAiClient; - - //public AzureOpenAIService(IConfiguration? config) - //{ - // if (config != null) - // { - // SubscriptionKey = config["AzureTranslateKey"] ?? ""; - // Endpoint = config["AzureTranslateUrl"] ?? ""; - // } - //} - - //public AzureOpenAIService(string key, string url) - //{ - // SubscriptionKey = key; - // Endpoint = url; - //} - - public AzureOpenAIService(OpenAIClient client) - { - _openAiClient = client; - } - - /*** - JSON 配置,它可以存储在您的secrets.json文件、appsettings.development.json或appsettings.json. - - "OpenAiClientConfiguration": { - "BaseUri": "[your_fqdn]", - "ApiKey": "[your_api_key]", - "DeploymentName": "[your_deployment_name]" - } - ***/ - public async Task GetTextCompletionResponse( - string input, int maxTokens) - { - var completionRequest = new CompletionRequest() - { - Prompt = input, - MaxTokens = maxTokens - }; - - return await _openAiClient - .GetTextCompletionResponseAsync(completionRequest); - } - - public async Task GetTextCompletionStreamingResponse( - string input, int maxTokens) - { - var completionRequest = new CompletionRequest() - { - Prompt = input, - MaxTokens = maxTokens - }; - - var stream = _openAiClient.StreamTextCompletionResponseAsync(completionRequest); - - if (stream == null) - { - return null; - } - - var res = string.Empty; - await foreach (var completionResponse in stream) - { - if (completionResponse != null && completionResponse?.Choices != null) - { - res += completionResponse.Choices?.FirstOrDefault()?.Text; - Console.Write(completionResponse.Choices?.FirstOrDefault()?.Text); - } - } - - return res; - } -} -#endif diff --git a/src/components/BootstrapBlazor.OCR/Services/StsService.cs b/src/components/BootstrapBlazor.OCR/Services/StsService.cs deleted file mode 100644 index bceeb229..00000000 --- a/src/components/BootstrapBlazor.OCR/Services/StsService.cs +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -using BootstrapBlazor.OCR.Services; -using Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models; -using Microsoft.Extensions.Configuration; -using System.Net.Http.Headers; -using System.Text; -using static BootstrapBlazor.AzureServices.Enums; -using Console = System.Console; - -namespace BootstrapBlazor.AzureServices; - -/// -/// STS 文本转语音服务 -/// -public partial class StsService : BaseService -{ - - public string SubscriptionKey = "your Computer Vision subscription key"; - - public string Endpoint = "https://api.cognitive.microsofttranslator.com"; - - public string FetchTokenUri = "https://westeurope.api.cognitive.microsoft.com/sts/v1.0/issueToken"; - - public string? Error; - - private string? token; - - private DateTime? lastRefreshTime; - - public StsService(IConfiguration? config) - { - if (config != null) - { - SubscriptionKey = config["AzureSsKey"] ?? ""; - FetchTokenUri = config["AzureSsFetchTokenUri"] ?? ""; - Endpoint = config["AzureSsUrl"] ?? ""; - } - } - - public StsService(string key, string url) - { - SubscriptionKey = key; - Endpoint = url; - } - - private async Task FetchTokenAsync(string fetchUri, string subscriptionKey) - { - using (var client = new HttpClient()) - { - client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey); - UriBuilder uriBuilder = new UriBuilder(fetchUri); - - var result = await client.PostAsync(uriBuilder.Uri.AbsoluteUri, null); - Console.WriteLine("Token Uri: {0}", uriBuilder.Uri.AbsoluteUri); - return await result.Content.ReadAsStringAsync(); - } - } - - - /// - /// 语音文件流生成 - /// - /// - /// - /// - /// - public async Task GetVoiceAsync(string speakText, string? voicename = "zh-HK-HiuGaaiNeural", string? style = "calm") - { - var ssml = speakText; - if (!ssml.StartsWith(" GetVoiceAsync(string ssml) - { - if (token == null || lastRefreshTime == null) - { - token = await FetchTokenAsync(FetchTokenUri, SubscriptionKey); - lastRefreshTime = DateTime.Now; - } - if (DateTime.Now - lastRefreshTime > TimeSpan.FromMinutes(9)) - { - token = await FetchTokenAsync(FetchTokenUri, SubscriptionKey); - lastRefreshTime = DateTime.Now; - } - using (var client = new HttpClient()) - { - var data = new StringContent(ssml, Encoding.UTF8, "application/ssml+xml"); - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); - client.DefaultRequestHeaders.Add("X-Microsoft-OutputFormat", "riff-24khz-16bit-mono-pcm"); - client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/ssml+xml")); - client.DefaultRequestHeaders.Add("User-Agent", "Densen TTS"); - UriBuilder uriBuilder = new UriBuilder(Endpoint); - - var response = await client.PostAsync(uriBuilder.Uri.AbsoluteUri, data); - if (response.IsSuccessStatusCode) - { - var wavBytes = await response.Content.ReadAsByteArrayAsync(); - return wavBytes; - } - else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized) - { - Console.WriteLine("Error: {0}", response.StatusCode); - token = FetchTokenAsync(FetchTokenUri, SubscriptionKey).Result; - return await GetVoiceAsync(ssml); - } - return null; - } - } - - private static string CreateSSML(string paramAudioText, string paramSelectedVoice, string paramSelectedStyle) - { - var ssml = @""; - ssml = ssml + @$""; - ssml = ssml + @$""; - ssml = ssml + @$"{paramAudioText}"; - ssml = ssml + @""; - ssml = ssml + @$""; - ssml = ssml + @$""; - return ssml; - } - - private string GetVoiceName(string name) => name switch - { - "zh-Hans" => AzureVoiceName.zh_CN_XiaomoNeural.GetEnumName(), - - "es" => AzureVoiceName.es_ES_AbrilNeural.GetEnumName(), - - "en" => AzureVoiceName.en_US_JennyNeural.GetEnumName(), - - "fr" => AzureVoiceName.fr_FR_BrigitteNeural.GetEnumName(), - - "ca" => AzureVoiceName.ca_ES_AlbaNeural.GetEnumName(), - - "zh-Hant" => AzureVoiceName.zh_HK_HiuGaaiNeural.GetEnumName(), - - "pt" => AzureVoiceName.pt_PT_FernandaNeural.GetEnumName(), - - "it" => AzureVoiceName.it_IT_FabiolaNeural.GetEnumName(), - - "de" => AzureVoiceName.de_DE_AmalaNeural.GetEnumName(), - - "pl" => AzureVoiceName.pl_PL_AgnieszkaNeural.GetEnumName(), - _ => name - }; - - -} - - - - diff --git a/src/components/BootstrapBlazor.OCR/Services/TranslateService.cs b/src/components/BootstrapBlazor.OCR/Services/TranslateService.cs deleted file mode 100644 index f7949bc2..00000000 --- a/src/components/BootstrapBlazor.OCR/Services/TranslateService.cs +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -// Website: https://www.blazor.zone or https://argozhang.github.io/ - -using BootstrapBlazor.OCR.Services; -using Microsoft.Azure.CognitiveServices.Vision.ComputerVision.Models; -using Microsoft.Extensions.Configuration; -using Newtonsoft.Json; -using System.ComponentModel.DataAnnotations; -using System.Globalization; -using System.Text; -using static BootstrapBlazor.AzureServices.TranslateResponse; -using Console = System.Console; - -namespace BootstrapBlazor.AzureServices; - -/// -/// 翻译 -/// -public partial class TranslateService : BaseService -{ - - public string SubscriptionKey = "your Computer Vision subscription key"; - - public string Endpoint = "https://api.cognitive.microsofttranslator.com"; - - - public TranslateService(IConfiguration? config) - { - if (config != null) - { - SubscriptionKey = config["AzureTranslateKey"] ?? ""; - Endpoint = config["AzureTranslateUrl"] ?? ""; - } - } - - public TranslateService(string key, string url) - { - SubscriptionKey = key; - Endpoint = url; - } - - - /// - /// 翻译 - /// - /// - /// - /// - public async Task?> Translate(string textToTranslate = "I would really like to drive your car around the block a few times!", string route = "/translate?api-version=3.0&to=es&to=en&to=fr&to=ca&to=zh-Hant&to=pt&to=it&to=de&to=pl") - { - try - { - //https://learn.microsoft.com/zh-cn/azure/cognitive-services/speech-service/language-support?tabs=speech-translation&WT.mc_id=DT-MVP-5005078 - - object[] body = new object[] { new { Text = textToTranslate } }; - var requestBody = JsonConvert.SerializeObject(body); - - using (var client = new HttpClient()) - using (var request = new HttpRequestMessage()) - { - // Build the request. - request.Method = HttpMethod.Post; - request.RequestUri = new Uri(Endpoint + route); - request.Content = new StringContent(requestBody, Encoding.UTF8, "application/json"); - request.Headers.Add("Ocp-Apim-Subscription-Key", SubscriptionKey); - // location required if you're using a multi-service or regional (not global) resource. - request.Headers.Add("Ocp-Apim-Subscription-Region", "westeurope"); - - // Send the request and get response. - HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false); - // Read response as a string. - var result0 = await response.Content.ReadAsStringAsync(); - var result = JsonConvert.DeserializeObject>(result0); - var result1 = result?.First()?.translations?.First()?.text; - Console.WriteLine(result1); - return result?.First()?.translations?.ToList(); - } - } - catch - { - return null; - - } - } -} - -public enum EnumTranslateLanguage -{ - [Display(Name = "中文")] - zh_cn, - [Display(Name = "西班牙文")] - es, - [Display(Name = "英文")] - en, - [Display(Name = "法文")] - fr, - [Display(Name = "加泰罗尼亚文")] - ca, - [Display(Name = "繁体中文")] - zh_Hant, - [Display(Name = "葡萄牙语")] - pt, - [Display(Name = "意大利语")] - it, - [Display(Name = "德语")] - de, - [Display(Name = "波兰语")] - pl, -} - - -//[{"detectedLanguage":{"language":"en","score":1.0},"translations":[{"text":"PRODUCTNAME_6","to":"es"},{ "text":"PRODUCTNAME_6","to":"en"}]}] -public class TranslateResponse -{ - - public Detectedlanguage? detectedLanguage { get; set; } - public Translation[]? translations { get; set; } - public class Detectedlanguage - { - public string? language { get; set; } - public float score { get; set; } - } - public class Translation - { - public string? text { get; set; } - public string? to { get; set; } - - public string? DisplayName { get => to != null ? new CultureInfo(to).DisplayName : "unknow"; } - } -} - - - diff --git a/src/components/BootstrapBlazor.OCR/Translate.razor b/src/components/BootstrapBlazor.OCR/Translate.razor deleted file mode 100644 index ccc36464..00000000 --- a/src/components/BootstrapBlazor.OCR/Translate.razor +++ /dev/null @@ -1,41 +0,0 @@ -@namespace BootstrapBlazor.Components - - - -
-
- -
-
-
-
- -
- @if (Result != null && Result.Any()) - { - foreach (var item in Result) - { -
-

@item.DisplayName

-