事业单位网站建设费科目,深圳建设网站哪家好,android开发是做什么的,淘宝培训应用场景
在日常工作和生活中#xff0c;我们经常会遇到需要对大量图片进行重命名的情况。例如#xff0c;设计师可能需要根据图片内容为设计素材命名#xff0c;文档管理人员可能需要根据扫描文档中的文字对图片进行分类命名。传统的手动重命名方式效率低下且容易出错我们经常会遇到需要对大量图片进行重命名的情况。例如设计师可能需要根据图片内容为设计素材命名文档管理人员可能需要根据扫描文档中的文字对图片进行分类命名。传统的手动重命名方式效率低下且容易出错因此开发一款能够自动识别图片中的文字并根据文字内容对图片进行重命名的工具具有很高的实用价值。 界面设计 我们可以设计一个简洁易用的 WPF 界面主要包含以下元素
顶部应用程序标题和版本信息中部 左侧文件选择区域包含文件夹选择按钮和已选择文件列表右侧预览区域显示当前选中的图片和识别结果 底部操作按钮区域包含开始处理、取消和设置按钮状态栏显示当前处理进度和状态信息
详细代码步骤
以下是实现咕嘎批量OCR识别图片PDF多区域内容重命名导出表格系统这个功能的详细代码步骤
创建 WPF 应用程序项目设计 XAML 界面实现JD OCR图片识别功能实现文件处理功能实现界面交互逻辑
下面是完整的代码实现
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.Win32;
using Newtonsoft.Json;
using RestSharp;namespace ImageOcrRenameTool
{/// summary/// MainWindow.xaml 的交互逻辑/// /summarypublic partial class MainWindow : Window{// 存储选择的图片文件路径private Liststring _selectedFiles new Liststring();// 当前选中的图片索引private int _currentIndex 0;// 京东OCR配置信息private OcrConfig _ocrConfig new OcrConfig();// 处理进度private int _processedCount 0;private int _totalCount 0;public MainWindow(){InitializeComponent();InitializeConfig();}// 初始化配置private void InitializeConfig(){try{if (File.Exists(config.json)){string json File.ReadAllText(config.json);_ocrConfig JsonConvert.DeserializeObjectOcrConfig(json);}}catch (Exception ex){MessageBox.Show($加载配置文件失败: {ex.Message}, 错误, MessageBoxButton.OK, MessageBoxImage.Error);}}// 保存配置private void SaveConfig(){try{string json JsonConvert.SerializeObject(_ocrConfig);File.WriteAllText(config.json, json);}catch (Exception ex){MessageBox.Show($保存配置文件失败: {ex.Message}, 错误, MessageBoxButton.OK, MessageBoxImage.Error);}}// 选择文件夹按钮点击事件private void BtnSelectFolder_Click(object sender, RoutedEventArgs e){using (var dialog new System.Windows.Forms.FolderBrowserDialog()){System.Windows.Forms.DialogResult result dialog.ShowDialog();if (result System.Windows.Forms.DialogResult.OK){string folderPath dialog.SelectedPath;LoadImages(folderPath);}}}// 加载文件夹中的图片private void LoadImages(string folderPath){try{// 清空现有文件列表_selectedFiles.Clear();lstFiles.Items.Clear();// 获取文件夹中所有支持的图片文件string[] imageExtensions { .jpg, .jpeg, .png, .bmp, .gif, .tiff };var files Directory.GetFiles(folderPath).Where(f imageExtensions.Contains(Path.GetExtension(f).ToLower()));foreach (var file in files){_selectedFiles.Add(file);lstFiles.Items.Add(Path.GetFileName(file));}if (_selectedFiles.Count 0){_currentIndex 0;LoadImage(_selectedFiles[_currentIndex]);UpdateStatus($已加载 {_selectedFiles.Count} 张图片);}else{UpdateStatus(未找到图片文件);}}catch (Exception ex){MessageBox.Show($加载图片失败: {ex.Message}, 错误, MessageBoxButton.OK, MessageBoxImage.Error);}}// 加载单张图片private void LoadImage(string filePath){try{// 显示图片BitmapImage bitmap new BitmapImage();bitmap.BeginInit();bitmap.CacheOption BitmapCacheOption.OnLoad;bitmap.UriSource new Uri(filePath);bitmap.EndInit();imgPreview.Source bitmap;// 显示文件名txtFileName.Text Path.GetFileName(filePath);// 更新文件索引信息lblFileIndex.Text $图片 {_currentIndex 1} / {_selectedFiles.Count};}catch (Exception ex){MessageBox.Show($加载图片失败: {ex.Message}, 错误, MessageBoxButton.OK, MessageBoxImage.Error);}}// 文件列表选择变更事件private void LstFiles_SelectionChanged(object sender, SelectionChangedEventArgs e){if (lstFiles.SelectedIndex 0){_currentIndex lstFiles.SelectedIndex;LoadImage(_selectedFiles[_currentIndex]);}}// 上一张图片按钮点击事件private void BtnPrev_Click(object sender, RoutedEventArgs e){if (_selectedFiles.Count 0 _currentIndex 0){_currentIndex--;lstFiles.SelectedIndex _currentIndex;}}// 下一张图片按钮点击事件private void BtnNext_Click(object sender, RoutedEventArgs e){if (_selectedFiles.Count 0 _currentIndex _selectedFiles.Count - 1){_currentIndex;lstFiles.SelectedIndex _currentIndex;}}// 开始处理按钮点击事件private async void BtnProcess_Click(object sender, RoutedEventArgs e){if (_selectedFiles.Count 0){MessageBox.Show(请先选择图片文件夹, 提示, MessageBoxButton.OK, MessageBoxImage.Information);return;}if (string.IsNullOrEmpty(_ocrConfig.AppKey) || string.IsNullOrEmpty(_ocrConfig.AppSecret)){MessageBox.Show(请先配置京东OCR的AppKey和AppSecret, 提示, MessageBoxButton.OK, MessageBoxImage.Information);ShowSettingsDialog();return;}// 禁用操作按钮btnSelectFolder.IsEnabled false;btnProcess.IsEnabled false;btnSettings.IsEnabled false;btnPrev.IsEnabled false;btnNext.IsEnabled false;// 重置进度_processedCount 0;_totalCount _selectedFiles.Count;progressBar.Value 0;lblProgress.Text 0%;// 异步处理图片await ProcessImagesAsync();// 恢复操作按钮btnSelectFolder.IsEnabled true;btnProcess.IsEnabled true;btnSettings.IsEnabled true;btnPrev.IsEnabled true;btnNext.IsEnabled true;}// 异步处理图片private async Task ProcessImagesAsync(){try{UpdateStatus(开始处理图片...);for (int i 0; i _selectedFiles.Count; i){string filePath _selectedFiles[i];_currentIndex i;// 在UI线程更新文件显示Dispatcher.Invoke(() {lstFiles.SelectedIndex i;UpdateStatus($正在处理: {Path.GetFileName(filePath)});});// 执行OCR识别string ocrResult await PerformOcrAsync(filePath);// 在UI线程更新识别结果Dispatcher.Invoke(() {txtOcrResult.Text ocrResult;});// 重命名文件if (!string.IsNullOrEmpty(ocrResult)){string newFileName GenerateNewFileName(ocrResult, filePath);await RenameFileAsync(filePath, newFileName);}// 更新进度_processedCount;Dispatcher.Invoke(() {double progress (double)_processedCount / _totalCount * 100;progressBar.Value progress;lblProgress.Text ${progress:F0}%;});}UpdateStatus($处理完成! 共处理 {_processedCount} 张图片);MessageBox.Show($处理完成! 共处理 {_processedCount} 张图片, 完成, MessageBoxButton.OK, MessageBoxImage.Information);}catch (Exception ex){UpdateStatus($处理失败: {ex.Message});MessageBox.Show($处理失败: {ex.Message}, 错误, MessageBoxButton.OK, MessageBoxImage.Error);}}// 执行OCR识别private async Taskstring PerformOcrAsync(string imagePath){try{// 创建RestClient和RestRequestvar client new RestClient(https://aiapi.jd.com/jdai/ocr_plate);var request new RestRequest(Method.POST);// 添加请求参数request.AddHeader(Content-Type, application/x-www-form-urlencoded);request.AddHeader(appkey, _ocrConfig.AppKey);// 读取图片文件并转换为Base64byte[] imageBytes File.ReadAllBytes(imagePath);string base64Image Convert.ToBase64String(imageBytes);// 添加请求体request.AddParameter(image, base64Image);request.AddParameter(appsecret, _ocrConfig.AppSecret);// 执行请求IRestResponse response await client.ExecuteAsync(request);if (response.IsSuccessful){// 解析JSON响应var result JsonConvert.DeserializeObjectJdOcrResponse(response.Content);if (result ! null result.code 0 result.data ! null result.data.words_result ! null){// 提取识别文本string ocrText string.Join( , result.data.words_result.Select(r r.words));return ocrText;}else{return $OCR识别失败: {result?.msg ?? 未知错误};}}else{return $请求失败: {response.StatusCode};}}catch (Exception ex){return $识别过程出错: {ex.Message};}}// 生成新文件名private string GenerateNewFileName(string ocrText, string originalPath){try{// 移除不允许的文件名字符string invalidChars new string(Path.GetInvalidFileNameChars());string cleanText ocrText;foreach (char c in invalidChars){cleanText cleanText.Replace(c, _);}// 限制文件名长度if (cleanText.Length 80){cleanText cleanText.Substring(0, 80);}// 添加时间戳以确保唯一性string timestamp DateTime.Now.ToString(yyyyMMdd_HHmmss);string baseName string.IsNullOrEmpty(cleanText.Trim()) ? unknown : cleanText.Trim();string newFileName ${baseName}_{timestamp}{Path.GetExtension(originalPath)};// 获取文件所在目录string directory Path.GetDirectoryName(originalPath);return Path.Combine(directory, newFileName);}catch (Exception){// 如果生成新文件名失败使用原始文件名加上时间戳string timestamp DateTime.Now.ToString(yyyyMMdd_HHmmss);string fileName Path.GetFileNameWithoutExtension(originalPath);string extension Path.GetExtension(originalPath);return Path.Combine(Path.GetDirectoryName(originalPath),${fileName}_{timestamp}{extension});}}// 异步重命名文件private async Task RenameFileAsync(string oldPath, string newPath){await Task.Run(() {try{// 如果新文件名已存在则添加序号if (File.Exists(newPath)){string directory Path.GetDirectoryName(newPath);string fileName Path.GetFileNameWithoutExtension(newPath);string extension Path.GetExtension(newPath);int counter 1;string tempPath;do{tempPath Path.Combine(directory, ${fileName}_{counter}{extension});counter;} while (File.Exists(tempPath));newPath tempPath;}// 重命名文件File.Move(oldPath, newPath);// 更新文件列表int index _selectedFiles.IndexOf(oldPath);if (index 0){_selectedFiles[index] newPath;// 在UI线程更新列表项Dispatcher.Invoke(() {if (lstFiles.Items.Count index){lstFiles.Items[index] Path.GetFileName(newPath);}});}}catch (Exception ex){Dispatcher.Invoke(() {MessageBox.Show($重命名文件失败: {ex.Message}, 错误, MessageBoxButton.OK, MessageBoxImage.Error);});}});}// 设置按钮点击事件private void BtnSettings_Click(object sender, RoutedEventArgs e){ShowSettingsDialog();}// 显示设置对话框private void ShowSettingsDialog(){var settingsWindow new SettingsWindow(_ocrConfig);if (settingsWindow.ShowDialog() true){_ocrConfig settingsWindow.OcrConfig;SaveConfig();}}// 更新状态栏信息private void UpdateStatus(string message){lblStatus.Text message;}// 鼠标滚轮事件 - 图片缩放private void ImgPreview_MouseWheel(object sender, MouseWheelEventArgs e){if (imgPreview.Source ! null){double scale e.Delta 0 ? 1.1 : 0.9;imgPreview.RenderTransform new ScaleTransform(scale, scale);imgPreview.RenderTransformOrigin new Point(0.5, 0.5);}}}// OCR配置类public class OcrConfig{public string AppKey { get; set; }public string AppSecret { get; set; }public bool UseJdOcr { get; set; } true;public string CustomApiUrl { get; set; }}// 京东OCR响应模型public class JdOcrResponse{public string code { get; set; }public string msg { get; set; }public OcrData data { get; set; }}public class OcrData{public ListWordsResult words_result { get; set; }}public class WordsResult{public string words { get; set; }}
}下面是 SettingsWindow 的代码
using System.Windows;namespace ImageOcrRenameTool
{/// summary/// SettingsWindow.xaml 的交互逻辑/// /summarypublic partial class SettingsWindow : Window{public OcrConfig OcrConfig { get; private set; }public SettingsWindow(OcrConfig config){InitializeComponent();OcrConfig new OcrConfig{AppKey config.AppKey,AppSecret config.AppSecret,UseJdOcr config.UseJdOcr,CustomApiUrl config.CustomApiUrl};DataContext OcrConfig;}private void BtnSave_Click(object sender, RoutedEventArgs e){DialogResult true;Close();}private void BtnCancel_Click(object sender, RoutedEventArgs e){DialogResult false;Close();}}
}下面是主窗口的 XAML 代码
Window x:ClassImageOcrRenameTool.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlTitle图片OCR重命名工具 v1.0 Height600 Width800WindowStartupLocationCenterScreenGrid!-- 顶部区域 --Grid.RowDefinitionsRowDefinition HeightAuto/RowDefinition Height*/RowDefinition HeightAuto/RowDefinition HeightAuto//Grid.RowDefinitions!-- 标题栏 --Border Grid.Row0 Background#333 Padding10TextBlock Text图片OCR重命名工具 ForegroundWhite FontSize16 FontWeightBold//Border!-- 主内容区域 --Grid Grid.Row1 Margin10Grid.ColumnDefinitionsColumnDefinition Width*/ColumnDefinition Width*//Grid.ColumnDefinitions!-- 左侧文件列表区域 --GroupBox Grid.Column0 Header文件列表 Margin0,0,5,0GridGrid.RowDefinitionsRowDefinition HeightAuto/RowDefinition Height*//Grid.RowDefinitionsButton x:NamebtnSelectFolder Content选择文件夹 HorizontalAlignmentLeft Margin5 Padding5,3ClickBtnSelectFolder_Click/ListBox x:NamelstFiles Grid.Row1 Margin5SelectionChangedLstFiles_SelectionChangedScrollViewer.HorizontalScrollBarVisibilityAuto//Grid/GroupBox!-- 右侧预览和OCR结果区域 --GroupBox Grid.Column1 Header预览和OCR结果 Margin5,0,0,0GridGrid.RowDefinitionsRowDefinition HeightAuto/RowDefinition Height*/RowDefinition HeightAuto/RowDefinition Height*//Grid.RowDefinitionsTextBlock Grid.Row0 Margin5 Text文件名:/TextBox x:NametxtFileName Grid.Row0 Margin60,5,5,5 IsReadOnlyTrue/ScrollViewer Grid.Row1 Margin5 HorizontalScrollBarVisibilityAutoVerticalScrollBarVisibilityAutoImage x:NameimgPreview StretchUniform MouseWheelImgPreview_MouseWheel//ScrollViewerTextBlock Grid.Row2 Margin5 TextOCR识别结果:/TextBox x:NametxtOcrResult Grid.Row3 Margin5 TextWrappingWrap VerticalScrollBarVisibilityAutoIsReadOnlyTrue//Grid/GroupBox/Grid!-- 图片导航区域 --Grid Grid.Row2 Margin10 HorizontalAlignmentCenterButton x:NamebtnPrev Content上一张 Padding8,5 Margin0,0,10,0 ClickBtnPrev_Click/Button x:NamebtnNext Content下一张 Padding8,5 Margin10,0,0,0 ClickBtnNext_Click/TextBlock x:NamelblFileIndex Margin10,0 VerticalAlignmentCenter FontSize12//Grid!-- 底部操作区域 --Grid Grid.Row3 Margin10Grid.ColumnDefinitionsColumnDefinition Width*/ColumnDefinition WidthAuto/ColumnDefinition WidthAuto/ColumnDefinition WidthAuto/ColumnDefinition WidthAuto//Grid.ColumnDefinitionsTextBlock x:NamelblStatus Grid.Column0 Margin5 VerticalAlignmentCenter FontSize12/ProgressBar x:NameprogressBar Grid.Column1 Margin5 Width200 Height20 VerticalAlignmentCenter/TextBlock x:NamelblProgress Grid.Column2 Margin5 VerticalAlignmentCenter FontSize12 Width40/Button x:NamebtnProcess Grid.Column3 Content开始处理 Padding8,5 Margin5 ClickBtnProcess_Click/Button x:NamebtnSettings Grid.Column4 Content设置 Padding8,5 Margin5 ClickBtnSettings_Click//Grid/Grid
/Window下面是设置窗口的 XAML 代码
Window x:ClassImageOcrRenameTool.SettingsWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlTitleOCR设置 Height300 Width400WindowStartupLocationCenterScreenResizeModeNoResizeGrid Margin10Grid.RowDefinitionsRowDefinition HeightAuto/RowDefinition HeightAuto/RowDefinition HeightAuto/RowDefinition HeightAuto/RowDefinition HeightAuto/RowDefinition Height*/RowDefinition HeightAuto//Grid.RowDefinitionsTextBlock Grid.Row0 Margin5 Text京东OCR设置/TextBlock Grid.Row1 Margin5 TextAppKey:/TextBox Grid.Row1 Margin80,5,5,5 Text{Binding AppKey}/TextBlock Grid.Row2 Margin5 TextAppSecret:/TextBox Grid.Row2 Margin80,5,5,5 Text{Binding AppSecret} PasswordChar*/CheckBox Grid.Row3 Margin5 Content使用京东OCR服务 IsChecked{Binding UseJdOcr}/TextBlock Grid.Row4 Margin5 Text自定义API地址:/TextBox Grid.Row4 Margin80,5,5,5 Text{Binding CustomApiUrl}/TextBlock Grid.Row5 Margin5 TextWrappingWrap FontSize10 ForegroundGrayText注意: 使用京东OCR服务需要先在京东AI开放平台注册并获取AppKey和AppSecret。/Grid Grid.Row6 Margin5Grid.ColumnDefinitionsColumnDefinition Width*/ColumnDefinition WidthAuto/ColumnDefinition WidthAuto//Grid.ColumnDefinitionsButton Grid.Column1 Content保存 Padding8,5 Margin0,0,5,0 ClickBtnSave_Click/Button Grid.Column2 Content取消 Padding8,5 Margin5,0,0,0 ClickBtnCancel_Click//Grid/Grid
/Window总结优化 功能总结 实现了批量选择图片文件的功能集成了JD OCR 服务进行文字识别根据识别结果自动重命名图片文件提供了友好的用户界面和操作体验支持图片预览和缩放功能提供了JD OCR 服务配置界面 性能优化 使用异步处理避免 UI 线程阻塞添加进度显示提升用户体验对重命名冲突进行了处理确保不会覆盖已有文件 安全考虑 将敏感的 OCR 配置信息保存到本地配置文件添加了异常处理确保程序在出现错误时不会崩溃文件操作时进行了冲突检测避免数据丢失 可扩展性 设计了可配置的 OCR 服务接口便于集成其他 OCR 服务可以进一步扩展功能如添加文件过滤、批量操作日志等 使用建议 在使用前需要在京东 AI 开放平台注册账号并获取 AppKey 和 AppSecret对于大量图片的处理建议分批进行避免内存占用过高识别结果可能受到图片质量、文字清晰度等因素影响
这个应用程序可以帮助用户高效地对图片进行重命名提高工作效率。在实际使用中你可以根据自己的需求进一步扩展和优化这个工具。