惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
D
Darknet – Hacking Tools, Hacker News & Cyber Security
N
News and Events Feed by Topic
N
News | PayPal Newsroom
SecWiki News
SecWiki News
P
Privacy International News Feed
T
Troy Hunt's Blog
Attack and Defense Labs
Attack and Defense Labs
N
News and Events Feed by Topic
L
LINUX DO - 热门话题
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Security Latest
Security Latest
AWS News Blog
AWS News Blog
S
Secure Thoughts
W
WeLiveSecurity
H
Heimdal Security Blog
T
Threat Research - Cisco Blogs
I
Intezer
Application and Cybersecurity Blog
Application and Cybersecurity Blog
S
Security @ Cisco Blogs
G
GRAHAM CLULEY
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Spread Privacy
Spread Privacy
L
Lohrmann on Cybersecurity
C
CERT Recently Published Vulnerability Notes
S
Security Affairs
Hacker News - Newest:
Hacker News - Newest: "LLM"
Google Online Security Blog
Google Online Security Blog
Cisco Talos Blog
Cisco Talos Blog
雷峰网
雷峰网
Cloudbric
Cloudbric
Y
Y Combinator Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园_首页
Hacker News: Ask HN
Hacker News: Ask HN
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Google DeepMind News
Google DeepMind News
Vercel News
Vercel News
云风的 BLOG
云风的 BLOG
Latest news
Latest news
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
D
Docker
Recent Announcements
Recent Announcements
博客园 - 【当耐特】
H
Help Net Security
博客园 - 司徒正美
TaoSecurity Blog
TaoSecurity Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
Check Point Blog
博客园 - 叶小钗

元视角

.NET 生态下的 Agent 框架选型:从 ReAct 到原生推理 - 元视角 从「能用」到「好用」:LLM 流式响应实现方式的探索之路 - 元视角 当我用 2000 条聊天记录,让 AI 为我画一幅自画像 - 元视角 基于 Supabase 的 AI 应用开发探索 - 元视角 微博 × MCP:社交媒体新玩法解锁 - 元视角 四点钟海棠花未眠 - 元视角 Semantic Kernel × MCP:智能体的上下文增强探索 - 元视角 基于 K-Means 聚类分析实现人脸照片的快速分类 - 元视角 容器技术驱动下的代码沙箱实践与思考 - 元视角 温故而知新:后端通用查询方案的再思考 - 元视角 浅议 CancellationToken 在前后端协同取消场景中的应用 - 元视角 Semantic Kernel 视角下的 Text2SQL 实践与思考 - 元视角 关于 ChatGPT 的流式传输,你需要知道的一切 - 元视角 RAG 的是与非、Rewrite 和 Rerank - 元视角 使用 EFCore 和 PostgreSQL 实现向量存储及检索 - 元视角 基于 LLaMA 和 LangChain 实践本地 AI 知识库 - 元视角 使用 llama.cpp 在本地部署 AI 大模型的一次尝试 - 元视角 如何为 Git 配置多个 SSH Key - 元视角 C# 使用 LibUsbDotNet 实现 USB 设备检测 - 元视角 基于 C# 实现样式与数据分离的打印方案 - 元视角 基于 SVG 的图形交互方案实践 - 元视角 前端视频播放技术概览 - 元视角 温故而知新,再话 Python 动态导入 - 元视角 后 GPT 时代,NLP 不存在了? - 元视角 视频是不能 P 的系列:使用 Milvus 实现海量人脸快速检索 - 元视角 GDI+下字体大小自适应方案初探 - 元视角 小爱音箱集成 ChatGPT 的不完全教程 - 元视角 程序员视角下的三体世界随想 - 元视角 关于 Docker 容器配置信息的渐进式思考 - 元视角 在 Docker 容器内集成 Crontab 定时任务 - 元视角 为你的服务器集成 LDAP 认证 - 元视角 似花还似非花 - 元视角 视频是不能 P 的系列:使用 Dlib 实现人脸识别 - 元视角 浅议分布式链路追踪与日志的整合 - 元视角 关于 Git 大文件上传这件小事 - 元视角 .NET 进程内队列 Channel 的入门与应用 - 元视角 使用 Fody 实现 .NET 的静态编织 - 元视角 .NET Core + ELK 搭建可视化日志分析平台(下) - 元视角 聊一聊前端图片懒加载背后的故事 - 元视角 支持外部链接跳转的 Vue Router 扩展实现 - 元视角 视频是不能 P 的系列:OpenCV 和 Dlib 实现表情包 - 元视角 不得不说的 ASP.NET Core 集成测试 - 元视角 再议 DDD 视角下的 EFCore 与 领域事件 - 元视角 Vue.js 前端项目容器化部署实践极简教程 - 元视角 再见,人间四月天 - 元视角 Python 图像风格化迁移助力画家梦想 - 元视角 利用 ASP.NET Core 中的标头传播实现分布式链路追踪 - 元视角 利用 gRPC 实现文件的上传与下载 - 元视角 七种武器:延迟队列的原理和实现总结 - 元视角 gRPC 流式传输极简入门指南 - 元视角 Envoy 集成 Jaeger 实现分布式链路追踪 - 元视角 浅议非典型 Web 应用场景下的身份认证 - 元视角 gRPC 借助 Any 类型实现接口的泛化调用 - 元视角 分布式丛林探险系列之 Redis 集群模式 - 元视角 分布式丛林探险系列之 Redis 主从复制模式 - 元视角 通过 Python 预测 2021 年双十一交易额 - 元视角 gRPC 搭配 Swagger 实现微服务文档化 - 元视角 SSL/TLS 加密传输与数字证书的前世今生 - 元视角 使用 Python 自动识别防疫健康码 - 元视角 你不可不知的容器编排进阶技巧 - 元视角 ASP.NET Core 搭载 Envoy 实现 gRPC 服务代理 - 元视角 再话 AOP,从简化缓存操作说起 - 元视角 ASP.NET Core 搭载 Envoy 实现微服务身份认证(JWT) - 元视角 ASP.NET Core 搭载 Envoy 实现微服务的监控预警 - 元视角 ASP.NET Core 搭载 Envoy 实现微服务的反向代理 - 元视角 ASP.NET Core gRPC 打通前端世界的尝试 - 元视角 EFCore 实体命名约定库:EFCore.NamingConventions - 元视角 ASP.NET Core gRPC 集成 Polly 实现优雅重试 - 元视角 ASP.NET Core gRPC 健康检查的探索与实现 - 元视角 ASP.NET Core gRPC 拦截器的使用技巧分享 - 元视角 SnowNLP 使用自定义语料进行模型训练 - 元视角 使用 HttpMessageHandler 实现 HttpClient 请求管道自定义 - 元视角 ABP vNext 的实体与服务扩展技巧分享 - 元视角 ABP vNext 对接 Ant Design Vue 实现分页查询 - 元视角 源代码探案系列之 .NET Core 跨域中间件 CORS - 元视角 源代码探案系列之 .NET Core 限流中间件 AspNetCoreRateLimit - 元视角 源代码探案系列之 .NET Core 并发限制中间件 ConcurrencyLimiter - 元视角 通过 EmbededFileProvider 实现 Blazor 的静态文件访问 - 元视角 低代码,想说爱你不容易 - 元视角 记一次失败的 ThoughtWorks 面试经历 - 元视角 从 C# 1.0 到 C# 9.0,历代 C# 语言特性一览 - 元视角 通过 Python 分析 2020 年全年微博热搜数据 - 元视角 基于 Python 和 Selenium 实现 CSDN 一键三连自动化 - 元视角 使用多线程为你的 Python 爬虫提速的 N 种姿势,你会几种? - 元视角 实现网页长截图的常见思路总结 - 元视角 温故而知新,由 ADO.NET 与 Dapper 所联想到的 - 元视角 视频是不能 P 的系列:OpenCV 人脸检测 - 元视角 作为技术宅的我,是这样追鬼滅の刃的 - 元视角 使用 Python 抽取《半泽直树》原著小说人物关系 - 元视角 厉害了!打工人用 Python 分析西安市职位信息 - 元视角 使用 dotTrace 对 .NET 应用进行性能分析与优化 - 元视角 一道 HashSet 面试题引发的蝴蝶效应 - 元视角 基于选项模式实现.NET Core 的配置热更新 - 元视角 Dapper.Contrib 在 Oracle 环境下引发 ORA-00928 异常问题的解决 - 元视角 .NET Core 中对象池(Object Pool)的使用 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(下):EventBus 篇 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(中):RabbitMQ 篇 - 元视角 利用 MySQL 的 Binlog 实现数据同步与订阅(上):基础篇 - 元视角 记一次从已损坏的 Git 仓库中找回代码的经历 - 元视角 .NET Core 原生 DI 扩展之属性注入实现 - 元视角
基于 Python 实现 Windows 下壁纸切换功能 - 元视角
飞鸿踏雪 · 2018-02-06 · via 元视角

  在过去一年多的时间里,我尝试改变博客的写作风格,努力让自己不再写教程类文章,即使在这个过程中,不断地面临着写作内容枯竭的痛苦。因为我渐渐地意识到,告诉别人如何去做一件事情,始终停留在"术"的层面,而比这个更为重要的是,告诉别人为什么要这样做,这样就可以过渡到"道"的层面。古人云:形而上者谓之道,形而下者谓之器。我们常常希望通过量变来产生质变,可是如果在这个过程中不能及时反思和总结,我们认为的努力或许仅仅是重复的劳作而已。如你所见,在这篇文章里,我们将通过 Python 和 Windows 注册表实现壁纸切换功能,主要涉及到的 Python 中的 requests、pyinstaller 这两个模块的使用,希望大家喜欢。

故事缘由

  人们常常相信事出有因,可这世界上有些事情,哪里会有什么原因啊,比如喜欢与不喜欢。做这样一个小功能的初衷,起源于我对桌面壁纸的挑剔。作为一个不完全的强迫症患者,我需要花费大量时间去挑选一张壁纸,丝毫不亚于在网上挑选一件喜欢的商品。我注意到知乎上有这样的话题:有哪些无版权图片网站值得推荐?,因此对于桌面壁纸的筛选,我渐渐地开始摆脱对搜索引擎的依赖,我个人比较喜欢PexelsUnsplash这两个网站,所以我想到了从这两个网站抓取图片来设置 Windows 壁纸的方案。市面上类似的商业软件有百度壁纸搜狗壁纸等,可这些软件都不纯粹,或多或少地掺杂了额外功能,个中缘由想来大家都是知道的。联想到微信最新版本的更新,“发现"页面支持所有项目的隐藏,甚至是盟友京东的电商入口和腾讯最赚钱的游戏入口,这让我开始正视腾讯这家公司,我收回曾经因为抄袭对腾讯产生的不满,腾讯是一家值得尊重的互联网公司。做一个纯粹的应用程序,这就是我的初心。

设计实现

  好了,现在我们考虑如何来实现这个功能,我们的思路是从Unsplash这个网站抓取图片,并将其存储在指定路径,然后通过 Windows API 完成壁纸的设置。Python 脚本会通过 pyinstaller 模块打包成可执行文件,我们通过修改注册表的方式,在右键菜单内加入切换壁纸的选项,这样我们可以直接通过右键菜单实现壁纸切换功能。在编写脚本的时候,起初想到的是抓包这样的常规思路,因为请求过程相对复杂而失败,后来意外地发现官方提供了 API 接口。事实上PexelsUnsplash都提供了 API 接口,通过调用这些 API 接口,我们的探索进行得非常顺利,下面是具体脚本实现:

# Query Images
searchURL = 'https://unsplash.com/napi/search?client_id=%s&query=%s&page=1'
client_id = 'fa60305aa82e74134cabc7093ef54c8e2c370c47e73152f72371c828daedfcd7'
categories = ['nature','flowers','wallpaper','landscape','sky']
searchURL = searchURL % (client_id,random.choice(categories))
response = requests.get(searchURL)
print(u'正在从Unsplash上搜索图片...')

# Parse Images
data = json.loads(response.text)
results = data['photos']['results']
print(u'已为您检索到图片共%s张' % str(len(results)))
results = list(filter(lambda x:float(x['width'])/x['height'] >=1.33,results))
result = random.choice(results)
resultId = str(result['id'])
resultURL = result['urls']['regular']

# Download Images
print(u'正在为您下载图片:%s...' % resultId)
basePath = sys.path[0]
if(os.path.isfile(basePath)):
    basePath = os.path.dirname(basePath)
baseFolder = basePath + '\\Download\\'
if(not path.exists(baseFolder)):
    os.makedirs(baseFolder)
jpgFile = baseFolder + resultId + '.jpg'
bmpFile = baseFolder + resultId + '.bmp'
response = requests.get(resultURL)
with open(jpgFile,'wb') as file:
    file.write(response.content)
img = Image.open(jpgFile)
img.save(bmpFile,'BMP')
os.remove(jpgFile)

  这部分代码非常简单,需要关注的地方有:第一,这个 API 对应的密钥是公共的,即所有人都可以使用,这里随机从指定的分类中去搜索图片。第二,这里使用 filter()函数过滤出宽高比超过 1.33 的图片,即分辨率为 1366 * 768 的图片。这里需要注意的是,在 Python3.X 下 filter 需要转化为 list,否则会引发一个异常。第三,下载的图片默认为 JPEG 格式,而 Windows 下设置壁纸使用的是位图格式,即 BMP 格式,所以在这里我们使用 PIL 模块来完成格式转换。这里需要注意的是,PIL 模块目前不支持 Python3.X 以后的版本,我们这里使用的是 Pillow 模块,该模块可以通过 pip 直接完成安装。

  现在,我们将壁纸下载到本地以后,就可以着手设置壁纸相关的工作。这些工作主要借助为 win32api 和 win32gui 这两个内置模块,我们一起来看具体代码:

print(u'正在设置图片:%s为桌面壁纸...' % resultId)
key = win32api.RegOpenKeyEx(win32con.HKEY_CURRENT_USER,
    "Control Panel\\Desktop",0,win32con.KEY_SET_VALUE)
win32api.RegSetValueEx(key, "WallpaperStyle", 0, win32con.REG_SZ, "2") 
#2拉伸适应桌面,0桌面居中
win32api.RegSetValueEx(key, "TileWallpaper", 0, win32con.REG_SZ, "0")
win32gui.SystemParametersInfo(win32con.SPI_SETDESKWALLPAPER, bmpFile, 1+2)
print(u'成功应用图片:%s为桌面壁纸'  % resultId)

  这部分内容非常简单,基本没有复杂的东西在里面。接下来我们需要通过 pyinstaller 模块将脚本打包成可执行文件,实际上这个步骤完全可以省略,因为现在我们通过命令行就可以实现壁纸切换,为什么要做这样额外的工作呢?考虑到 Windows 下 GUI 更为便捷一点,所以我们打包成可执行文件,主要是为了给右键菜单添加功能,我们最终点击想要实现的功能是,点击右键菜单就可以完成壁纸的切换。首先通过 pip 安装 pyinstaller 模块,在终端下执行命令:

python -m pip install pyinstaller

安装完成后按照官方文档即可在./dist/目录中找到生成的可执行文件,如果打包出错可以修改 Python 根目录下的./Scripts/pyinstaller-script.py 文件,修改第一行 Python.exe 的路径,删除两端的引号即可,如下图所示。关于 pyinstaller 模块打包时的详细参数设定,请自行查阅官方文档。

pyinstaller-script.py文件 pyinstaller-script.py文件

  现在,在生成可执行文件以后,我们打开注册表,定位到以下节点: 计算机\HKEY_CLASSES_ROOT\Directory\Background\shell,然后创建一级子节点 WallPaper,其默认值填写"更换壁纸”,接下来创建二级子节点 command,注意这个名称不能修改,其默认值填写可执行文件路径,本例中为:E:\Software\WallPaper\main.exe,如下图所示:

为右键菜单增加更换壁纸选项 为右键菜单增加更换壁纸选项

  好了,现在我们可以看看在右键菜单中增加"更换壁纸"选项以后的效果: 最终效果 最终效果

文本小结

  本文使用 Python 实现了 Windows 下切换壁纸的功能,通过 requests 模块从网络上抓取图片,通过 PIL 模块实现 JPEG 格式到 BMP 格式的转换,通过 win32api 和 win32gui 模块实现壁纸设置,并通过修改注册表的方式,将这一功能整合到系统菜单中,可以非常便捷地更换桌面壁纸。作为一个设计上的扩展,我们需要考虑更多的问题,比如当网络断开的时候如何避免异常,如何接入更多的在线图库 API,如何支持可配置的图片分类信息以及如何将修改注册表的过程自动化等等,这些问题博主会利用空闲时间去解决,今天这篇文章就是这样啦,本文源代码可以通过这里获取,谢谢大家!