QiniuUpload- 一个方便用七牛做图床然后插入markdown的小工具

时间:2023-01-06 23:26:00

  最近一段时间有用markdown做笔记,其他都好,但是markdown插入图片挺麻烦的,特别是想截图之后直接插入的时候。需要首先把图片保存了,然后还要上传到一个地方生成链接才能插入。如果有个工具可以直接上传图片或者截图生成markdown可以用的链接就好了。所以决定自己下班后写一个,不过自己挺菜的,也就能用,代码完全是渣不能看。。。在这里把自己的思路还有其中遇到的问题记录一下。

  首先需要选一个图床,我选了七牛,主要是一个是有免费的空间,加上提供了SDK,这样就能写程序上传了。语言挑了C#,因为感觉WPF写界面还算方便吧。根据七牛文档写得,首先要用nuget下载官方的SDK,这个可以参考http://developer.qiniu.com/code/v6/sdk/csharp.html

  所要完成的功能:能够选择图片上传,能够自动上传截图,生成markdown可用的链接

1、界面

主界面:

  QiniuUpload- 一个方便用七牛做图床然后插入markdown的小工具

设置账号界面:

QiniuUpload- 一个方便用七牛做图床然后插入markdown的小工具

2. 选择图片上传功能

点击中间区域弹出文件浏览框,选择图片后上传。这个通过绑定控件的鼠标事件来完成,上传图片用到了七牛提供的API。主体函数如下,首先是通过比对文件的hash值来判断是否本地以及远程已经有过上传,如果没有上传过,就通过七牛提供的上传API进行上传,并在预览区显示图片。

 private bool UpLoadFile(string filepath)
{
string filename = System.IO.Path.GetFileName(filepath);
Qiniu.Util.Mac lMac = new Qiniu.Util.Mac(UserAccount.AccessKey, UserAccount.SecretKey);
string lRemoteHash = RemoteFileInfo.RemoteFileStat(lMac, UserAccount.SpaceName, filename);
bool lSkip = false;
bool lUpLoadSuccess = false;
//check local
string lLocalHash = String.Empty;
if (!string.IsNullOrEmpty(lRemoteHash))
{
lLocalHash = QETag.hash(filepath); if (historyLog.ContainsKey(lLocalHash))
{
if(historyLog[lLocalHash].Contains(filename))
{
lSkip = true;
URL = CreateURL(filename);
lUpLoadSuccess = true;
}
}
else if (string.Equals(lLocalHash, lRemoteHash))
{
lSkip = true;
URL = CreateURL(filename);
lUpLoadSuccess = true;
}
}
if (!lSkip)
{
putPolicy.Scope = UserAccount.SpaceName;
putPolicy.SetExpires( * * );
string lUploadToken = Auth.createUploadToken(putPolicy, lMac);
UploadManager lUploadMgr = new UploadManager();
lUploadMgr.uploadFile(filepath, filename, lUploadToken, null, new UpCompletionHandler(delegate (string key, ResponseInfo responseinfo, string response)
{
if (responseinfo.StatusCode != )
{
MessageStr = Properties.Resources.ErrorMessage;
}
else
{
MessageStr = Properties.Resources.SuccessMessage;
if (historyLog.ContainsKey(lLocalHash))
{
historyLog[lLocalHash].Add(filename);
}
URL = CreateURL(filename);
lUpLoadSuccess = true;
}
}));
} if (lUpLoadSuccess)
{
DisplayImage(filepath);
MessageStr = URL;
} return lUpLoadSuccess;
}

3. 截图上传

为了完成这个,搜了下资料,需要用到win32的两个函数,分别是AddClipboardFormatListener以及RemoveClipboardFormatListener,然后检查系统消息是否是WM_CLIPBOARDUPDATE。为了给用户提供选择是否开启这个,在主界面上添加了一个button来控制是否开启。因为七牛SDK的上传api的参数是一个文件路径,所以这里我首先会将截图存储到本地再上传。

     private void CBViewerButton_Click(object sender, RoutedEventArgs e)
{
if(!IsViewing)
{
InitCBViewer();
this.CBViewerButton.Content = "停止监控";
}
else
{
StopCBViewer();
this.CBViewerButton.Content = "监控剪切板";
}
}
private void InitCBViewer()
{
WindowInteropHelper lwindowih = new WindowInteropHelper(this);
hWndSource = HwndSource.FromHwnd(lwindowih.Handle); hWndSource.AddHook(this.WndProc);
Win32.AddClipboardFormatListener(hWndSource.Handle);
IsViewing = true;
} private void StopCBViewer()
{
Win32.RemoveClipboardFormatListener(hWndSource.Handle);
hWndSource.RemoveHook(this.WndProc);
IsViewing = false;
} private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParm, ref bool handled)
{
if(msg == Win32.WM_CLIPBOARDUPDATE)
{
ProcessClipBoard();
}
return IntPtr.Zero;
} private void ProcessClipBoard()
{
if(System.Windows.Clipboard.ContainsImage())
{
MessageStr = Properties.Resources.UpLoading; BmpBitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(System.Windows.Clipboard.GetImage())); string lFileName = CreateFileName();
string lSaveFilePath = System.IO.Path.Combine(Properties.Resources.ImageSavePathDir, lFileName);
using (FileStream fs = new FileStream(lSaveFilePath, FileMode.OpenOrCreate, FileAccess.Write))
{
enc.Save(fs);
fs.Close();
} //because unkown reason, when use wechat snapshot hotkey, the message will process twice, to avoid this, check whether we save the same file
string lLocalHash = QETag.hash(lSaveFilePath);
if(historyLog.ContainsKey(lLocalHash))
{
File.Delete(lSaveFilePath);
URL = CreateURL(historyLog[lLocalHash][]);
lSaveFilePath = System.IO.Path.Combine(Properties.Resources.ImageSavePathDir, historyLog[lLocalHash][]);
}
else
{
if(!UpLoadFile(lSaveFilePath))
{
File.Delete(lSaveFilePath);
}
}
}
}

PS:在做这个的时候我碰到一个问题就是当我用微信的截图快捷键的时候,这个Clipboard事件会被触发两次,为了解决这个,我的做法是判断本地的上传记录,比对文件的hash值。如果已经上传过,就把后来又存储的文件给删除掉。目前我也想不到其他方式,暂且这样处理吧。

4. 账号设置

用七牛做图床需要设置四个参数,分别是目标空间名,Accesskey, secrectkey以及域名。为了方便存储和读取,用了C#里的xml序列化和反序列化

  if (File.Exists(Properties.Resources.ConfigFilePath))
{
XmlSerializer xs = new XmlSerializer(typeof(AccountInfo));
using (Stream s = File.OpenRead(Properties.Resources.ConfigFilePath))
{
UserAccount = (AccountInfo)(xs.Deserialize(s));
}
}
  using (Stream s = File.OpenWrite(Properties.Resources.ConfigFilePath))
{
XmlSerializer xs = new XmlSerializer(typeof(AccountInfo));
xs.Serialize(s, MainWindow.UserAccount);
}

5. 未完成功能:历史记录查看等

完整代码:

https://github.com/HaoLiuHust/QiniuUpload

PS: 代码很烂,还需要多练

QiniuUpload- 一个方便用七牛做图床然后插入markdown的小工具的更多相关文章

  1. win10 uwp 使用 asp dotnet core 做图床服务器客户端

    原文 win10 uwp 使用 asp dotnet core 做图床服务器客户端 本文告诉大家如何在 UWP 做客户端和 asp dotnet core 做服务器端来做一个图床工具   服务器端 从 ...

  2. 分享一个超级好用的SM图床

    分享一个超级好用的SM图床 ​ 大家都知道我是一个喜欢sm Markdown的人,但是Markdown有个很不方便的地方,就是图片的插入,一般用Markdown编辑器(我用的是Typora)直接插入图 ...

  3. 图床plus演示 | 图床及在线分享演示文稿工具

    文章目录 关于图床 什么是图床? 墙内 墙外 关于在线分享演示文稿 在线分享演示文稿 工具分享 待补充 关于图床 什么是图床? 这并不是一个多么高大上的名词概念!用比较通俗的话来说,当你在撰写新文章时 ...

  4. u-tools图床便捷生成markdown图片

    u-tools 图床 上传图片生成markdown图片非常便捷. 支持的图片服务器有几种,其中搜狗.网易和掘金的加载速度更快些: 也可以用阿里与和腾讯云的OSS; 其中网易生成图片不是原图尺寸好像被改 ...

  5. 使用GitHub API上传文件及GitHub做图床

    本文介绍GitHub API基础及上传文件到仓库API,并应用API将GitHub作为图床 GitHub API官方页面 GitHub API版本 当前版本为v3,官方推荐在请求头中显示添加版本标识. ...

  6. 自己做的加速app测试流程的小工具,目前打算开放使用,想注册的朋友抓紧了,嘻嘻

    为了加速小团队app的测试流程做了这个东西,www.xunce.net 主要特性: web: 一键上传app,方便随时下载 备注测试要点 添加附件,如checklist等文档  自动识别app版本,名 ...

  7. Markdown编辑器及图床推荐

    Typora和自动图床工具 Typora 地址 ,极致简洁,界面很漂亮,最重要的是所见即所得 百度云搬运 密码:xi01 自动图床工具 需要七牛云做图床,感谢作者,详见博客 使用方法,只需两步即可完成 ...

  8. 网易云免费OSS服务用做Markdown图床或博客图片外链

    我使用据说是Windows下最好用的Markdown编辑器“MarkdownPad2”(个人感觉还是Visual Code+Markdown插件666)写Markdown,在贴图方面遇到一个问题,于是 ...

  9. 有道云笔记配合MPic+七牛云 自制MarkDown文档图床(适用Typora)

    注:从有道云笔记v6.5开始,有道云笔记会员可以使用MarkDown有道自带的图床.(但是非会员可以采用下面的七牛云图床+MarkDown方法) 0x00 前言 一直用有道云笔记,粘贴图片,做笔记没问 ...

随机推荐

  1. mybatis源码分析:

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "Helvetica Neue"; color: #e4af0a } p. ...

  2. rem、px、em之间的区别以及网页响应式设计写法

    个人收藏用,转载自:http://www.w3cplus.com/css3/define-font-size-with-css3-rem 在Web中使用什么单位来定义页面的字体大小,至今天为止都还在激 ...

  3. .NET工程师面试宝典

    .Net工程师面试笔试宝典 传智播客.Net培训班内部资料 这套面试笔试宝典是传智播客在多年的教学和学生就业指导过程中积累下来的宝贵资料,大部分来自于学员从面试现场带过来的真实笔试面试题,覆盖了主流的 ...

  4. Qt StyleSheet皮肤css源码

    使用方式如下 //设置皮肤样式 static void SetStyle(const QString &styleName) { QFile file(QString(":/imag ...

  5. windows 常用命令

    1 Services.msc  在运行输入 启动所有安装程序配置

  6. jQuery验证控件(转载)

    转自:http://www.cnblogs.com/hejunrex/archive/2011/11/17/2252193.html 官网地址:http://bassistance.de/jquery ...

  7. 这两个成员函数inline重新virtual种类

    inlineType表示在编译时扩展功能,随着在函数调用的函数体而出替换函数调用:和vitual它是c++多态的必要条件,但为了表现出多态性,您将需要等到执行,要知道什么是真正的函数调用.从表面上看这 ...

  8. SQLServer之创建嵌套触发器

    嵌套触发器创建规则 当触发器执行启动其他触发器的操作时,DML 和 DDL 触发器都是嵌套触发器. 这些操作都可以启动其他触发器等. DML 触发器和 DDL 触发器最多可以嵌套 32 层. 可以通过 ...

  9. valueForKeyPath用途

    可能大家对- (id)valueForKeyPath:(NSString *)keyPath方法不是很了解. 其实这个方法非常的强大,举个例子: NSArray *array = @[@"n ...

  10. Tomcat manager页面报403

    一.前言 我这边已经配置了tomcat-users.xml: <tomcat-users xmlns="http://tomcat.apache.org/xml" xmlns ...