Alfred 有多强悍,我写了个一键上传图片的 workflow 来告诉你

简介: Alfred 有多强悍,我写了个一键上传图片的 workflow 来告诉你

前言



一直以来用的都是 MarkEditor 写作,它有一个比较重要的功能:能自动将拷贝到编辑器中的截图同步到图床,这样如果要将文章导出发到其他平台,由于本地的图片在导出后自动转成了链接,所以无需担心图片在其他平台的识别问题。



但是最近发现文章同步到掘金或 CSDN 这些平台时,这些图片链接居然无法转存到他们的平台,应该是 markeditor 的图床用了防盗链技术导致图片无法转存。


画外音:在掘金,CSDN 这些第三方平台发文时,一般会将文中非本平台的图片链接转存为本平台的,防止第三方图片链接失效导致文章中的图片在平台展示有问题。


那么该怎么解决呢,有两种方式


  1. 一种是找到那些粘贴图片后可以自动上传图床并且生成的图片链接没有防盗链的平台,如 mdnice.com, 不过我试了一下 mdnice.com,貌似有 bug,Chrome 和 Safari 上粘贴图片后自动上传图片不起作用,360浏览器倒是可以。
  2. 另一种是在 MarkEditor 里设置其他图床,比如七牛云等,这样可以配置七牛云的图片不采用防盗链技术,但是要配置七牛云这样的图床,一来要收费,二来要去注册帐号,申请域名备案等等,有点麻烦。


考虑之后我决定自己整一个自动上传到图床的工具,无它,自己实现比较 Cool,怎么做呢,一般本地图片要转成最终的图床链接有以下两步


  1. 剪切或者复制图片
  2. 将图片上传到云端,上传成功后会返回云端的图片链接


我希望这个工具能达到如下流程图所示的效果:



复制图片/截图后,按下快捷键,自动完成之后上传图片到图床----->获取图片地址----->转成 markdown 中的图片地址(即** ![](云端图片url) **这种形式)并将其 copy 到剪切板,这样我在 markdown 编辑器粘贴即可获取云端图片链接。


技术选型



使用一个快捷键就能完成后面的所有操作,第一时间我想到了 Alfred 的  workflow,Alfred 堪称是 Mac 的第一神器,它是一个用键盘通过热键、关键字、自定义插件来加快操作效率的工具,它不但是搜索工具,还是快速启动工具,甚至能够操作许多系统功能,扩充性极强,其中自定义插件是其核心功能,主要通过 workflow 实现, 什么是 workflow 呢,我们知道一个大的任务可以分解成一个个的小任务(work),这些小任务通过输入输出组合起来就能完成这个大任务,这样一个个 work 组合起来就形成了一个工作流(workflow)



其中每一个 work 可以由 php, python 等多个编程语言编写,通过 workflow 可以串起各个 work 的输入输出,这样只要触发一下快捷键,workflow 就能自动执行,最终会得到一个结果,比如我之前就写了一个时间戳日期互相转换的 workflow,如下:



在 workflow 中输入 ts(快捷键),后面跟着你要展示的时间戳/日期,即可将其转成日期/时间戳,非常方便。我们在日常中可以将一些重复的工作来用 workflow 实现,这样只要输入一个快捷键即可自动触发,能省下我们很多时间,不亦乐乎!


一键上传图片 workflow 实现思路



上节可知 workflow 确实强大,所以用它来实现我们的自动上传图片到图床的功能再合适不过了。


首先我选择了蛋壳(imgkr.com/)这个免费又稳定的图床… charles(或其他抓包工具)然后上传一张图片,成功后可以在 charles 看到上传图片的请求



然后我们看看这个上传图片的请求到底是咋样的,按以下步骤,点击  Copy as cURL,可以看看这个 curl 请求长啥样



拷贝出来后的 curl 请求长这样



从图中可以看到, curl 请求的请求部分除了图片的二进制数据是动态变化,其他都是固定的,图片的二进制数据无疑是从剪切板中来的,于是问题转化为了如何从剪切板中获取图片数据。


如何从剪切板中获取图片数据呢,这里介绍一个工具: pngpaste, 它可以将图片从剪切板中导出到指定路径,先用 brew 安装一下这个工具


brew install pngpaste
复制代码


安装之后我们就可以用以下命令将剪切板中的图片导到指定路径了


pngpaste 图片路径
复制代码


于是问题转化成如何获取指定路径图片的二进制数据,shell 做不到,不过 php 可以做到,所以我们最终用 php 重写了上文中的 curl 请求,也就是说我们最终选择用 php 来完成最终的 workflow, 最终的 php 实现的思路如下:



如有兴趣可以看下如下代码实现,注释写得很详尽了,相信大家应该能看懂


// 将剪切板中的图片拷贝到指定的路径
$command = '/usr/local/bin/pngpaste /tmp/test.jpeg';
$output = shell_exec($command);
require 'workflows.php';
$wf = new Workflows();
// 加载图片二进制数据
$data = file_get_contents('/tmp/test.jpeg');
// 以下为上传图片逻辑
$ch = curl_init('http://imgkr.com/api/v2/files/upload');
$boundary = 'WebKitFormBoundaryCQV3KALJwjBXA5ue';
$files = ['171f3cdebc5586.jpeg' => $data];
$delimiter = '-------------' . $boundary;
$data = '';
foreach ($files as $name => $content) {
    $data .= "--" . $delimiter . "\r\n"
        . 'Content-Disposition: form-data; name="file"; filename="' . $name . '"' . "\r\nContent-Type: image/jpeg" . "\r\n\r\n"
        . $content . "\r\n";
}
$data .= "--" . $delimiter . "--\r\n";
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: multipart/form-data; boundary=' . $delimiter,
        'Content-Length: ' . strlen($data),
        'Host: imgkr.com',
        'User-Agent: Mozilla/5.0 (Macintosh, Intel Mac OS X 10_15_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36',
        'X-Requested-With: XMLHttpRequest',
        'Accept: */*',
        'Origin: https://imgkr.com',
        'Sec-Fetch-Site: same-origin',
        'Sec-Fetch-Mode: cors',
        'Sec-Fetch-Dest: empty',
        'Referer: https://imgkr.com/',
        'Accept-Language: zh,en-US,q=0.9,en,q=0.8,zh-CN,q=0.7',
        'Cookie: _ga=GA1.2.377288389.1594181932, _gid=GA1.2.851545805.1594809662, _gat=1',
    ],
    CURLOPT_POSTFIELDS => $data
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');
$test = json_decode(curl_exec($ch));
// 以下三行为上传图片成功后,将其转化为 markdown 中的图片格式并将其写入剪切板中,这样最终在 markdown 中粘贴后即为对应的 markdown 图片链接
$result = '\'![](' . $test->data . ')\'';
$copy = "echo $result | pbcopy";
shell_exec($copy);
$query = '';
$result = '拷贝到剪切板成功!';
$wf->result($query, $result, $result, $query, 'icon.png');
echo $wf->toxml();
复制代码


画外音:workflows.php 是用 php 写 workflow 的一个辅助插件,能在 Alfred 的下拉框中展示我们需要的结果,大家如有兴趣可以去 github.com/joetannenba… 进一步了解一下


配置 workflow



脚本既然写好,那配置 workflow 自然不在话下,新建的 workflow 如下:



以上 workflow 表示当按下「shift+cmd+s」时(即图片中的 Hotkey),会自动执行对应的脚本(Script Filter)将剪切板中的图片上传到图床(执行图片中的脚本 Script Filter),并最终将云端图片转成 markdown 的图片url 并拷贝到剪切板。这样我们只要在编辑器执行一下粘贴命令即可得到我们想要的云端图片 url,效果如下图所示,workflow 成功执行后会在 Alfred 的下拉框中展示「拷贝到剪切板成功」这个信息。



从此以后,如果我想截图并且获取此图片的链接即可一键搞定!再也不要机械的手动上传图片了!是不是很 Cool!


总结



工具化,自动化是工程师非常重要的思维方式,我们应该把重复低效的工作工具化,自动化,把有限的时候投入在更值得做的事情上去,就像现在的自动化测试等也是为了用工具化,自动化的思维帮助研发测试人员从重复低效的工作中解脱出来。workflow 无疑给我们提供了一个很好的手段,日常工作中,我们可以借助 workflow 来提升我们的工作效率!

相关文章
|
Java 大数据 API
用上myexcel,百万数据导出也不怕
用上myexcel,百万数据导出也不怕
453 0
|
前端开发
【HTML+CSS+JS】前端三剑客实现3D旋转照片墙
前端三剑客实现3D旋转照片墙
1185 0
【HTML+CSS+JS】前端三剑客实现3D旋转照片墙
|
12月前
|
机器学习/深度学习 自然语言处理 PyTorch
LLM-Mixer: 融合多尺度时间序列分解与预训练模型,可以精准捕捉短期波动与长期趋势
近年来,大型语言模型(LLMs)在自然语言处理领域取得显著进展,研究人员开始探索将其应用于时间序列预测。Jin等人提出了LLM-Mixer框架,通过多尺度时间序列分解和预训练的LLMs,有效捕捉时间序列数据中的短期波动和长期趋势,提高了预测精度。实验结果显示,LLM-Mixer在多个基准数据集上优于现有方法,展示了其在时间序列预测任务中的巨大潜力。
300 3
LLM-Mixer: 融合多尺度时间序列分解与预训练模型,可以精准捕捉短期波动与长期趋势
|
9月前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
379 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
9月前
|
存储 人工智能 算法
解锁分布式文件分享的 Java 一致性哈希算法密码
在数字化时代,文件分享成为信息传播与协同办公的关键环节。本文深入探讨基于Java的一致性哈希算法,该算法通过引入虚拟节点和环形哈希空间,解决了传统哈希算法在分布式存储中的“哈希雪崩”问题,确保文件分配稳定高效。文章还展示了Java实现代码,并展望了其在未来文件分享技术中的应用前景,如结合AI优化节点布局和区块链增强数据安全。
|
12月前
|
机器学习/深度学习 前端开发 JavaScript
WebAssembly:让前端性能突破极限的秘密武器
WebAssembly(简称 WASM)作为前端开发的性能加速器,能够让代码像 C++ 一样在浏览器中高速运行,突破了 JavaScript 的性能瓶颈。本文详细介绍了 WebAssembly 的概念、工作原理以及其在前端性能提升中的关键作用。通过与 JavaScript 的配合,WASM 让复杂运算如图像处理、3D 渲染、机器学习等在浏览器中流畅运行。文章还探讨了如何逐步集成 WASM,展示其在网页游戏、高计算任务中的实际应用。WebAssembly 为前端开发者提供了新的可能性,是提升网页性能、优化用户体验的关键工具。
5226 2
WebAssembly:让前端性能突破极限的秘密武器
|
人工智能 算法 前端开发
打破传统叙事逻辑,构建基于原子化任务的人机交互
在复杂中后台设计中,为解决配置变更影响多场景问题,提出结合正向和逆向信息架构,采用原子化任务,动态组合任务,降低用户和开发成本,优化体验并改变已有的产品迭代和人机交互模式。未来可能发展为AI自动根据业务规则和用户行为生成最佳方案。
|
监控 测试技术 持续交付
如何在 Databricks 中实现 CI CD 管道?
【8月更文挑战第13天】
187 2
|
JSON JavaScript 关系型数据库
低代码使用问题之Automat和n8n分别是什么,以及它们的主要功能是什么
低代码使用问题之Automat和n8n分别是什么,以及它们的主要功能是什么
|
消息中间件 Kubernetes Java
MQ产品使用合集之RocketMQ发消息失败了,proxy报connect to null failed如何解决
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
2039 2
MQ产品使用合集之RocketMQ发消息失败了,proxy报connect to null failed如何解决