网站首页 > 技术文章 正文
因为我的照片中的拍摄日期被软件修改,我想通过查找exif信息来找回拍摄日期,所以找了几个相关的软件来进行这项工作,但没有任何效果。于是就想通过写代码来自己提取exif信息。
当然我对于这方面工作毫无所知,于是就借助了人工智能,我所采用的方式是使用百度的”文心一言“,当然是3.5免费版,就算如此,编程的实践也给了我足够的惊喜。
具体方法就是向人工智能提出要求,然后人工智能就给出了代码。我把这个代码粘贴到VS里运行。
第一次运行的时候,明显缺少一个类库,我继续向人工智能提问,它给出一如何安装这个类库的建议。
第二次运行的时候,有一些语句出错了,我告诉人工智能出错的提示,并要求它继续给出一个完整的代码,这样我就可以不用费心去研究如何排除错误。人工智能很快给出了修改后的代码,我又把这些代码直接粘贴到VS里运行。
当然,程序又出错了。我就又重复上面的过程,不断要求人工智能修改代码。
最后,程序完全正确的运行起来,虽然最后我还没有找到照片拍摄的原始日期,但这是一次非常成功的编程实践。
我能确定,如果不是人工智能辅助,要编写这个程序,我首先要了解exif信息方面的知识,并且在互联网上大海捞针一样寻找合适的类库,最后还要查看英文的文档及看示例程序,最后才能写出这些代码。这个过程,最大的问题就在于我要不断地试验那些类库,确保我找到的是可以使用的比较成熟的,这个过程,非常的枯燥,就像是大海捞针,再试验针是不是生锈了还能使用。
下面是我调试成功的代码,虽然很简单,但谁知道您下一次写类似程序的时候,人工智能是不是从这些代码中又学习了新的知识,会写出Bug更少的代码呢?这一切都是可能发生的,谁会知道人工智能可以走得多远呢?
如果不是年龄太大了,我真有一种创业的冲动,以后,非常可能的,一个人也可以是一个公司,因为有无数的人工智能是你的不开工资的助理,你只要决策就行了。
<Window x:Class="ExifViewer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="EXIF Viewer" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Name="ImageControl" Grid.Row="0" Stretch="Uniform"/>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<StackPanel Name="ExifInfoPanel"/>
</ScrollViewer>
<Button Grid.Row="2" Content="Select Image" HorizontalAlignment="Center" VerticalAlignment="Center" Click="SelectImage_Click"/>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Media.Imaging;
using Microsoft.Win32;
using MetadataExtractor;
using MetadataExtractor.Formats.Exif;
using System.Windows.Controls;
namespace ExifViewer
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void SelectImage_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog
{
Filter = "Image Files|*.jpg;*.jpeg;*.png;*.bmp;*.gif",
Title = "Select an Image File"
};
bool? result = openFileDialog.ShowDialog();
if (result == true)
{
string filePath = openFileDialog.FileName;
LoadImageAndExifInfo(filePath);
}
}
private void LoadImageAndExifInfo(string filePath)
{
try
{
// Load the image
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = new Uri(filePath, UriKind.Absolute);
bitmap.EndInit();
ImageControl.Source = bitmap;
// Load and display EXIF info
var directories = ImageMetadataReader.ReadMetadata(filePath).OfType<MetadataExtractor.Directory>().Where(d => d is ExifIfd0Directory || d is ExifSubIfdDirectory).ToList();
DisplayExifInfo(directories);
}
catch (Exception ex)
{
MessageBox.Show(#34;Error: {ex.Message}");
}
}
private void DisplayExifInfo(List<MetadataExtractor.Directory> directories)
{
ExifInfoPanel.Children.Clear();
foreach (var directory in directories)
{
if (directory is ExifIfd0Directory exif0)
{
AddExifInfoSection("EXIF IFD0", exif0);
}
else if (directory is ExifSubIfdDirectory exifSub)
{
AddExifInfoSection("EXIF SubIFD", exifSub);
}
// Add more sections for other EXIF directories if needed, e.g., ExifThumbnailDirectory, GpsDirectory, etc.
}
}
private void AddExifInfoSection(string sectionTitle, MetadataExtractor.Directory directory)
{
var sectionTextBlock = new TextBlock
{
Text = sectionTitle,
FontWeight = FontWeights.Bold,
Margin = new Thickness(0, 10, 0, 5)
};
ExifInfoPanel.Children.Add(sectionTextBlock);
foreach (var tag in directory.Tags)
{
var tagTextBlock = new TextBlock
{
Text = #34;{tag.Name}: {tag.Description ?? "N/A"}", // Use "N/A" for null descriptions
Margin = new Thickness(10, 0, 0, 0)
};
ExifInfoPanel.Children.Add(tagTextBlock);
}
var endTagTextBlock = new TextBlock { Text = "提取信息结束", Margin = new Thickness(10, 0, 0, 0) };
ExifInfoPanel.Children.Add(endTagTextBlock);
// Add a separator (using a Rectangle as WPF doesn't have a Separator in a StackPanel by default)
//var separator = new Rectangle
//{
// Margin = new Thickness(0, 5, 0, 10),
// Height = 1,
// Fill = Brushes.LightGray
//};
//ExifInfoPanel.Children.Add(separator);
}
}
}
猜你喜欢
- 2024-12-28 游戏画面绘图 透明特效的制作方法
- 2024-12-28 Lazarus 打印 raz打印方法
- 2024-12-28 Android 性能优化工具篇:如何使用 DDMS 中的 TraceView 工具
- 2024-12-28 「3D效果图」法线贴图的正确使用方法和技巧
- 2024-12-28 TF Lite Model Maker: 构建安卓图片分类器
- 2024-12-28 用户界面控件Xtreme Calendar发布v17.0.0
- 2024-12-28 UG各版本安装时出现报警问题及解决方法
- 2024-12-28 6.1 用Bitmap实现精确去重 bitmap字符串去重
- 2024-12-28 MFC常用函数与指令 mfcformat函数
- 2024-12-28 MFC中双缓冲技术 双缓冲技术java
- 02-21走进git时代, 你该怎么玩?_gits
- 02-21GitHub是什么?它可不仅仅是云中的Git版本控制器
- 02-21Git常用操作总结_git基本用法
- 02-21为什么互联网巨头使用Git而放弃SVN?(含核心命令与原理)
- 02-21Git 高级用法,喜欢就拿去用_git基本用法
- 02-21Git常用命令和Git团队使用规范指南
- 02-21总结几个常用的Git命令的使用方法
- 02-21Git工作原理和常用指令_git原理详解
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)