【图片识别改名】如何批量将图片按图片上文字重命名?自动批量识别图片文字并命名,基于图片文字内容改名,WPF和京东ocr识别的解决方案

news2025/6/9 8:03:40

应用场景

在日常工作和生活中,我们经常会遇到需要对大量图片进行重命名的情况。例如,设计师可能需要根据图片内容为设计素材命名,文档管理人员可能需要根据扫描文档中的文字对图片进行分类命名。传统的手动重命名方式效率低下且容易出错,因此开发一款能够自动识别图片中的文字并根据文字内容对图片进行重命名的工具具有很高的实用价值。

界面设计

我们可以设计一个简洁易用的 WPF 界面,主要包含以下元素:

  1. 顶部:应用程序标题和版本信息
  2. 中部:
    • 左侧:文件选择区域,包含文件夹选择按钮和已选择文件列表
    • 右侧:预览区域,显示当前选中的图片和识别结果
  3. 底部:操作按钮区域,包含开始处理、取消和设置按钮
  4. 状态栏:显示当前处理进度和状态信息

详细代码步骤

以下是实现咕嘎批量OCR识别图片PDF多区域内容重命名导出表格系统这个功能的详细代码步骤:

  1. 创建 WPF 应用程序项目
  2. 设计 XAML 界面
  3. 实现JD OCR图片识别功能
  4. 实现文件处理功能
  5. 实现界面交互逻辑

下面是完整的代码实现:

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 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        // 存储选择的图片文件路径
        private List<string> _selectedFiles = new List<string>();
        // 当前选中的图片索引
        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.DeserializeObject<OcrConfig>(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 Task<string> PerformOcrAsync(string imagePath)
        {
            try
            {
                // 创建RestClient和RestRequest
                var 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);
                
                // 读取图片文件并转换为Base64
                byte[] 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.DeserializeObject<JdOcrResponse>(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 List<WordsResult> words_result { get; set; }
    }

    public class WordsResult
    {
        public string words { get; set; }
    }
}

下面是 SettingsWindow 的代码:

using System.Windows;

namespace ImageOcrRenameTool
{
    /// <summary>
    /// SettingsWindow.xaml 的交互逻辑
    /// </summary>
    public 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:Class="ImageOcrRenameTool.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="图片OCR重命名工具 v1.0" Height="600" Width="800"
        WindowStartupLocation="CenterScreen">
    <Grid>
        <!-- 顶部区域 -->
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        
        <!-- 标题栏 -->
        <Border Grid.Row="0" Background="#333" Padding="10">
            <TextBlock Text="图片OCR重命名工具" Foreground="White" FontSize="16" FontWeight="Bold"/>
        </Border>
        
        <!-- 主内容区域 -->
        <Grid Grid.Row="1" Margin="10">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            
            <!-- 左侧文件列表区域 -->
            <GroupBox Grid.Column="0" Header="文件列表" Margin="0,0,5,0">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    
                    <Button x:Name="btnSelectFolder" Content="选择文件夹" 
                            HorizontalAlignment="Left" Margin="5" Padding="5,3"
                            Click="BtnSelectFolder_Click"/>
                    
                    <ListBox x:Name="lstFiles" Grid.Row="1" Margin="5"
                             SelectionChanged="LstFiles_SelectionChanged"
                             ScrollViewer.HorizontalScrollBarVisibility="Auto"/>
                </Grid>
            </GroupBox>
            
            <!-- 右侧预览和OCR结果区域 -->
            <GroupBox Grid.Column="1" Header="预览和OCR结果" Margin="5,0,0,0">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    
                    <TextBlock Grid.Row="0" Margin="5" Text="文件名:"/>
                    <TextBox x:Name="txtFileName" Grid.Row="0" Margin="60,5,5,5" 
                             IsReadOnly="True"/>
                    
                    <ScrollViewer Grid.Row="1" Margin="5" HorizontalScrollBarVisibility="Auto"
                                  VerticalScrollBarVisibility="Auto">
                        <Image x:Name="imgPreview" Stretch="Uniform" MouseWheel="ImgPreview_MouseWheel"/>
                    </ScrollViewer>
                    
                    <TextBlock Grid.Row="2" Margin="5" Text="OCR识别结果:"/>
                    <TextBox x:Name="txtOcrResult" Grid.Row="3" Margin="5" 
                             TextWrapping="Wrap" VerticalScrollBarVisibility="Auto"
                             IsReadOnly="True"/>
                </Grid>
            </GroupBox>
        </Grid>
        
        <!-- 图片导航区域 -->
        <Grid Grid.Row="2" Margin="10" HorizontalAlignment="Center">
            <Button x:Name="btnPrev" Content="上一张" Padding="8,5" 
                    Margin="0,0,10,0" Click="BtnPrev_Click"/>
            <Button x:Name="btnNext" Content="下一张" Padding="8,5" 
                    Margin="10,0,0,0" Click="BtnNext_Click"/>
            <TextBlock x:Name="lblFileIndex" Margin="10,0" 
                       VerticalAlignment="Center" FontSize="12"/>
        </Grid>
        
        <!-- 底部操作区域 -->
        <Grid Grid.Row="3" Margin="10">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            
            <TextBlock x:Name="lblStatus" Grid.Column="0" Margin="5" 
                       VerticalAlignment="Center" FontSize="12"/>
            
            <ProgressBar x:Name="progressBar" Grid.Column="1" Margin="5" 
                         Width="200" Height="20" VerticalAlignment="Center"/>
            
            <TextBlock x:Name="lblProgress" Grid.Column="2" Margin="5" 
                       VerticalAlignment="Center" FontSize="12" Width="40"/>
            
            <Button x:Name="btnProcess" Grid.Column="3" Content="开始处理" 
                    Padding="8,5" Margin="5" Click="BtnProcess_Click"/>
            
            <Button x:Name="btnSettings" Grid.Column="4" Content="设置" 
                    Padding="8,5" Margin="5" Click="BtnSettings_Click"/>
        </Grid>
    </Grid>
</Window>

下面是设置窗口的 XAML 代码:

<Window x:Class="ImageOcrRenameTool.SettingsWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="OCR设置" Height="300" Width="400"
        WindowStartupLocation="CenterScreen"
        ResizeMode="NoResize">
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        
        <TextBlock Grid.Row="0" Margin="5" Text="京东OCR设置"/>
        
        <TextBlock Grid.Row="1" Margin="5" Text="AppKey:"/>
        <TextBox Grid.Row="1" Margin="80,5,5,5" Text="{Binding AppKey}"/>
        
        <TextBlock Grid.Row="2" Margin="5" Text="AppSecret:"/>
        <TextBox Grid.Row="2" Margin="80,5,5,5" Text="{Binding AppSecret}" 
                 PasswordChar="*"/>
        
        <CheckBox Grid.Row="3" Margin="5" Content="使用京东OCR服务" 
                  IsChecked="{Binding UseJdOcr}"/>
        
        <TextBlock Grid.Row="4" Margin="5" Text="自定义API地址:"/>
        <TextBox Grid.Row="4" Margin="80,5,5,5" Text="{Binding CustomApiUrl}"/>
        
        <TextBlock Grid.Row="5" Margin="5" TextWrapping="Wrap" 
                   FontSize="10" Foreground="Gray"
                   Text="注意: 使用京东OCR服务需要先在京东AI开放平台注册并获取AppKey和AppSecret。"/>
        
        <Grid Grid.Row="6" Margin="5">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            
            <Button Grid.Column="1" Content="保存" Padding="8,5" 
                    Margin="0,0,5,0" Click="BtnSave_Click"/>
            <Button Grid.Column="2" Content="取消" Padding="8,5" 
                    Margin="5,0,0,0" Click="BtnCancel_Click"/>
        </Grid>
    </Grid>
</Window>

总结优化

  1. 功能总结

    • 实现了批量选择图片文件的功能
    • 集成了JD OCR 服务进行文字识别
    • 根据识别结果自动重命名图片文件
    • 提供了友好的用户界面和操作体验
    • 支持图片预览和缩放功能
    • 提供了JD OCR 服务配置界面
  2. 性能优化

    • 使用异步处理避免 UI 线程阻塞
    • 添加进度显示,提升用户体验
    • 对重命名冲突进行了处理,确保不会覆盖已有文件
  3. 安全考虑

    • 将敏感的 OCR 配置信息保存到本地配置文件
    • 添加了异常处理,确保程序在出现错误时不会崩溃
    • 文件操作时进行了冲突检测,避免数据丢失
  4. 可扩展性

    • 设计了可配置的 OCR 服务接口,便于集成其他 OCR 服务
    • 可以进一步扩展功能,如添加文件过滤、批量操作日志等
  5. 使用建议

    • 在使用前需要在京东 AI 开放平台注册账号并获取 AppKey 和 AppSecret
    • 对于大量图片的处理,建议分批进行,避免内存占用过高
    • 识别结果可能受到图片质量、文字清晰度等因素影响

这个应用程序可以帮助用户高效地对图片进行重命名,提高工作效率。在实际使用中,你可以根据自己的需求进一步扩展和优化这个工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2405136.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RabbitMQ 的高可用性

RabbitMQ 是比较有代表性的&#xff0c;因为是基于主从&#xff08;非分布式&#xff09;做高可用的RabbitMQ 有三种模式&#xff1a;单机模式、普通集群模式、镜像集群模式。 单机模式 单机模式,生产几乎不用。 普通集群模式&#xff08;无高可用性&#xff09; 普通集群模…

AI架构师修炼之道

1 AI时代的架构革命 与传统软件开发和软件架构师相比&#xff0c;AI架构师面临着三重范式转换&#xff1a; 1.1 技术维度&#xff0c;需处理异构算力调度与模型生命周期管理的复杂性&#xff1b; 1.2 系统维度&#xff0c;需平衡实时性与资源约束的矛盾&#xff1b; 1.3 价…

iview组件库:当后台返回到的数据与使用官网组件指定的字段不匹配时,进行修改某个属性名再将response数据渲染到页面上的处理

1、需求导入 当存在前端需要的数据的字段渲染到表格或者是一些公共的表格组件展示数据时的某个字段名与后台返回的字段不一致时&#xff0c;那么需要前端进行稍加处理&#xff0c;而不能直接this.list res.data;这样数据是渲染不出来的。 2、后台返回的数据类型 Datalist(pn) …

服务器 | Centos 9 系统中,如何部署SpringBoot后端项目?

系列文章目录 虚拟机 | Ubuntu 安装流程以及界面太小问题解决 虚拟机 | Ubuntu图形化系统&#xff1a; open-vm-tools安装失败以及实现文件拖放 虚拟机 | Ubuntu操作系统&#xff1a;su和sudo理解及如何处理忘记root密码 文章目录 系列文章目录前言一、环境介绍二、 使用syst…

(2025)Windows修改JupyterNotebook的字体,使用JetBrains Mono

(JetBrains Mono字体未下载就配置,这种情况我不知道能不能行,没做过实验,因为我电脑已经下载了,不可能删了那么多字体做实验,我的建议是下载JetBrains Mono字体,当你使用VsCode配置里面的JetBrains字体也很有用) 首先参考该文章下载字体到电脑上 VSCode 修改字体为JetBrains …

小番茄C盘清理:专业高效的电脑磁盘清理工具

在使用电脑的过程中&#xff0c;我们常常会遇到系统盘空间不足、磁盘碎片过多、垃圾文件堆积等问题&#xff0c;这些问题不仅会导致电脑运行缓慢&#xff0c;还可能引发系统崩溃。为了解决这些问题&#xff0c;小番茄C盘清理应运而生。它是一款专业的C盘清理软件&#xff0c;能…

AUTOSAR实战教程--标准协议栈实现DoIP转DoCAN的方法

目录 软件架构 关键知识点 第一:PDUR的缓存作用 第二:CANTP的组包拆包功能 第三:流控帧的意义 配置过程 步骤0:ECUC模块中PDU创建 步骤1:SoAD模块维持不变 步骤2:DoIP模块为Gateway功能添加Connection ​步骤3:DoIP模块为Gateway新增LA/TA/SA ​步骤4:PDUR模…

【MySQL系列】MySQL 导出表数据到文件

博客目录 一、使用 SELECT INTO OUTFILE 语句基本语法参数详解注意事项实际示例 二、使用 mysqldump 工具基本语法常用选项实际示例 三、使用 MySQL Workbench 导出导出步骤高级选项 四、其他导出方法1. 使用 mysql 命令行客户端2. 使用 LOAD DATA INFILE 的逆向操作3. 使用编程…

vue3:十五、管理员管理-页面搭建

一、页面效果 实现管理员页面,完成管理员对应角色的中文名称显示,实现搜索栏,表格基本增删改查,分页等功能 二、修改问题 1、修改搜索框传递参数问题 (1)问题图示 如下图,之前搜索后,传递的数据不直接是一个value值,而是如下图的格式 查询可知这里传递的数据定义的是…

基于51单片机的红外防盗及万年历仿真

目录 具体实现功能 设计介绍 资料内容 全部内容 资料获取 具体实现功能 具体功能&#xff1a; &#xff08;1&#xff09;实时显示年、月、日、时、分、秒、星期信息&#xff1b; &#xff08;2&#xff09;红外传感器&#xff08;仿真中用按键模拟&#xff09;检测是否有…

【飞腾AI加固服务器】全国产化飞腾+昇腾310+PCIe Switch的AI大模型服务器解决方案

以下是全国产化飞腾AI加固服务器采用飞腾昇腾PCIe Switch解决方案&#xff1a; &#x1f5a5;️ 一、硬件架构亮点 ‌国产算力双擎‌ ‌飞腾处理器‌&#xff1a;搭载飞腾FT2000/64核服务器级CPU&#xff08;主频1.8-2.2GHz&#xff09;&#xff0c;支持高并发任务与复杂计算&a…

应用层协议:HTTPS

目录 HTTPS&#xff1a;超文本传输安全协议 1、概念 2、通信过程及关键技术 2.1 通信过程 1> TLS握手协商&#xff08;建立安全通道&#xff09; 2> 加密数据传输 2.2 关键技术 1> 对称加密算法 2> 非对称加密 3> 对称加密和非对称加密组合 4> 数…

【ArcGIS技巧】—村庄规划规划用地规划状态字段生成工具

"国土空间规划后续也是走向数据治理&#xff0c;数据建库已经是涉及到城市规划、建筑、市政、农业、地理信息、测绘等等方方面面。不得不说以后数据库建设跟维护&#xff0c;是很多专业的必修课。小编就湖南省的村庄规划建库过程中规划用地用海中规划状态字段写了个小工具…

【PCIe总线】-- inbound、outbound配置

PCI、PCIe相关知识整理汇总 【PCIe总线】 -- PCI、PCIe相关实现 由之前的PCIe基础知识可知&#xff0c;pcie的组成有&#xff1a;RC&#xff08;根节点&#xff09;、siwtch&#xff08;pcie桥&#xff09;、EP&#xff08;设备&#xff09;。 RC和EP&#xff0c;以及EP和EP能…

分布式锁实战:Redisson vs. Redis 原生指令的性能对比

分布式锁实战&#xff1a;Redisson vs. Redis 原生指令的性能对比 引言 在DIY主题模板系统中&#xff0c;用户可自定义聊天室的背景、图标、动画等元素。当多个运营人员或用户同时修改同一模板时&#xff0c;若没有锁机制&#xff0c;可能出现“甲修改了背景色&#xff0c;乙…

react+taro 开发第五个小程序,解决拼音的学习

1.找一个文件夹 cmd 2.taro init 3.vscode 找开该文件夹cd help-letters 如&#xff1a;我的是(base) PS D:\react\help-letters> pnpm install 4.先编译一下吧。看下开发者工具什么反应。 pnpm dev:weapp 5.开始规则。我用cursor就是不成功。是不是要在这边差不多了&…

kafka(windows)

目录 介绍 下载 配置 测试 介绍 Kafka是一个分布式流媒体平台&#xff0c;类似于消息队列或企业信息传递系统。 下载 Kafka对于Zookeeper是强依赖&#xff0c;所以安装Kafka之前必须先安装zookeeper 官网&#xff1a;Apache Kafka 下载此安装包并解压 配置 新建log…

基于安卓的文件管理器程序开发研究源码数据库文档

摘 要 伴随着现代科技的发展潮流&#xff0c;移动互联网技术快速发展&#xff0c;各种基于通信技术的移动终端设备做的也越来越好了&#xff0c;现代智能手机大量的进入到了我们的生活中。电子产品的各种软硬技术技术的发展&#xff0c;操作系统的不断更新换代&#xff0c;谷歌…

EMC VNXe 存储系统日志收集方法

写在前面 有朋友找来看看VNXe的故障&#xff0c;这种问题总是要收集日志&#xff0c;顺便这里也分享给大家。 注意&#xff0c;VNXe和VNX 属于完全不同的产品&#xff0c;不要看名字很类似&#xff0c;操作系统已经完全重构了&#xff0c;如果说是否有联系&#xff0c;大概就…

从“人找政策”到“政策找人”:智能退税ERP数字化重构外贸生态

离境退税新政核心内容与外贸企业影响 &#xff08;一&#xff09;政策核心变化解析 退税商店网络扩容 新政明确鼓励在大型商圈、旅游景区、交通枢纽等境外旅客聚集地增设退税商店&#xff0c;并放宽备案条件至纳税信用M级企业。以上海为例&#xff0c;静安区计划新增1000家退…