2015年7月20日更新1.2版,弹窗确认框一秒后自动关闭,并增加了对中文路径的支持。
单exe下载地址链接: 百度网盘 请输入提取码 密码: 6aba
包含pngquant和qt动态链接库下载地址链接: 百度网盘 请输入提取码 密码: tf3a
我不知道这么打包别人的软件和dll是不是违反了协议啥的,如有请告知,谢谢。
程序实现的功能非常简单:读取剪贴板中的图片,保存为png文件,调用pngquant来压缩成新的png,把压缩后的png文件的路径写入剪贴板(相当于在资源管理器中对这个文件做“复制”操作)。
使用方法是:用各种截屏软件截屏到剪贴板,运行这个小程序,在需要粘贴的地方粘贴。
这个小程序是不后台运行的,运行完就退出。运行方法可以是用各种快捷运行工具比如"WIN+R"、“ALTRUN”等,也可以创建exe的快捷方式,在属性里添加全局快捷键。
下面以win7为例介绍如何建立快捷方式和快捷键:
首先在png-1s.exe上右键,选择“创建快捷方式”,同一文件夹下就会出现一个名为“png-1s.exe - 快捷方式”的文件。
然后在这个快捷方式文件上右键,选择“属性”,弹出属性对话框。
点击“快捷方式”选项卡,如下图,①处可以在后面添加一个空格,再添加一个数字,代表弹窗过多少毫秒自动关闭,不添加这个参数就是默认1000毫秒,此参数范围是100-100000也就是0.1秒到100秒。②处可以设置快捷键,但是如果快捷键已经被其他软件注册了也是不会提醒的。设置完后点击确定按钮。接下来可以把快捷方式放到桌面,或者锁定到任务栏,或者发送给altrun,或者拷贝到system文件夹。如果设置了快捷键就可以随时按下设置的快捷键启动这个程序了。
这个小程序还有一个附加功能,就是运行时也会从剪贴板读取文本,如果是淘宝或天猫的URL就会简化URL,去掉spm等参数,只保留id参数。这是我整理购物清单时需要用的功能,因为只有几行代码,同时也需要做剪贴板操作,就和上面的程序合体了。
程序编译完是个exe,和pngquant.exe放到同一目录下,路径需要是纯英文的。我不会静态编译,所以还得把一大堆QT的dll也放到同一目录。
整个程序的代码是从网上东拼西凑的,我不是搞编程的,程序很粗糙还请包涵。基于QT5,源码如下:
#include "mainwindow.h"
#include <QApplication>
#include <QtGui>
#include <QMessageBox>
#include <QMimeData>
#include <QDebug>
#include <string.h>
#include <windows.h>
#include <shlobj.h>
//复制文件到剪贴板
//没有加入错误判断,请自行修改
int CopyFileToClipboard(const char szFileName[])
{
UINT uDropEffect;
HGLOBAL hGblEffect;
LPDWORD lpdDropEffect;
DROPFILES stDrop;
HGLOBAL hGblFiles;
LPSTR lpData;
uDropEffect = RegisterClipboardFormatA("Preferred DropEffect");
hGblEffect = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE,sizeof(DWORD));
lpdDropEffect = (LPDWORD)GlobalLock(hGblEffect);
*lpdDropEffect = DROPEFFECT_COPY;//复制; 剪贴则用DROPEFFECT_MOVE
GlobalUnlock(hGblEffect);
stDrop.pFiles = sizeof(DROPFILES);
stDrop.pt.x = 0;
stDrop.pt.y = 0;
stDrop.fNC = FALSE;
stDrop.fWide = FALSE;
hGblFiles = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE,\
sizeof(DROPFILES)+strlen(szFileName)+2);
lpData = (LPSTR)GlobalLock(hGblFiles);
memcpy(lpData,&stDrop,sizeof(DROPFILES));
strcpy(lpData+sizeof(DROPFILES),szFileName);
GlobalUnlock(hGblFiles);
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_HDROP,hGblFiles);
SetClipboardData(uDropEffect,hGblEffect);
CloseClipboard();
return 1;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//MainWindow w;
//w.show();
//从剪贴板中读取图片并保存为png图片
QImage myImage1=QImage(QApplication::clipboard()->image());
if(myImage1.isNull()) {
QString str = QApplication::clipboard()->text();
qDebug() << str;
if(str.left(7)=="http://"){
str = str.mid(7);
}
int istaobaourl=0;
if(str.left(25)=="item.taobao.com/item.htm?"){
str = str.mid(25);
qDebug()<<str;
QStringList slist = str.split('&');
for(int i=0;i<slist.size();i++){
qDebug() << slist[i];
if(slist[i].startsWith("id=")){
str="http://item.taobao.com/item.htm?"+slist[i];
qDebug() << str ;
QApplication::clipboard()->setText(str);
istaobaourl=1;
}
}
}
else if(str.left(26)=="detail.tmall.com/item.htm?"){
str = str.mid(26);
qDebug()<<str;
QStringList slist = str.split('&');
for(int i=0;i<slist.size();i++){
qDebug() << slist[i];
if(slist[i].startsWith("id=")){
str="http://detail.tmall.com/item.htm?"+slist[i];
qDebug() << str ;
QApplication::clipboard()->setText(str);
istaobaourl=1;
}
}
}
if(istaobaourl==1){
QMessageBox::information(NULL, "淘宝URL简化成功",str);
return 0;
}
else{
QMessageBox::information(NULL, "出错了","未能从剪贴板中读取图片或淘宝URL");
return -1;
}
}
myImage1.copy().save("temp.png");
//调用pngquant压缩图片
QProcess p(0);
p.start("pngquant.exe --force --verbose --ordered --speed=1 --quality=50-90 temp.png");
p.waitForStarted();
p.waitForFinished();
/*
//把压缩后的图片写入剪贴板中
QImage myImage2("temp-or8.png");
QApplication::clipboard()->clear();
QApplication::clipboard()->setImage(myImage2);
myImage1=QImage(QApplication::clipboard()->image());
*/
//读取原图片大小
QFile file0("temp.png");
if (!file0.open(QIODevice::ReadOnly)){
QMessageBox::information(NULL, "出错了","未能读取原图片");
return -2;
}
qint64 filesize0 = file0.size();
file0.close();
//读取压缩后图片大小
QFile file1("temp-or8.png");
if (!file1.open(QIODevice::ReadOnly)) {
QMessageBox::information(NULL, "出错了","未能读取压缩后的图片");
return -3;
}
qint64 filesize1 = file1.size();
file1.close();
QDir temDir("temp-or8.png");
QString absDir = temDir.absolutePath();
qDebug()<<absDir;
std::string sstr = absDir.toStdString();
const char* ch = sstr.c_str();
CopyFileToClipboard(ch);
//根据原文件大小自动匹配单位
QString fs0,fs1,str;
if(filesize0<1024) {
fs0.sprintf("%d 字节",(int)filesize0);
fs1.sprintf("%d 字节",(int)filesize1);
}
else if(filesize0<1024*1024){
fs0.sprintf("%.1f KB",(float)filesize0/1024);
fs1.sprintf("%.1f KB",(float)filesize1/1024);
}
else{
fs0.sprintf("%.1f MB",(float)filesize0/1024/1024);
fs1.sprintf("%.1f MB",(float)filesize1/1024/1024);
}
//计算压缩比,根据文件大小的方式或许有问题,尤其是对于很小的图片会出现大于100%的压缩比。
str.sprintf("%.1f%%",(float)filesize1*100/(float)filesize0);
str="截图压缩成功,原图片大小为 "+fs0+",压缩后图片大小为 "+fs1+",压缩率为 "+str+" ,压缩后的图片已经写入剪贴板中。";
QMessageBox::information(NULL, "截图压缩成功", str);
return 0;//a.exec();
}
一秒版源码下载链接: 百度网盘 请输入提取码 密码: sy2n
为什么写这个程序:我在做笔记的时候经常会用到截图功能,但是我发现有道云笔记和office对于图片的压缩都很“谨慎”,一张1080p截图大小能有200多k,现在硬盘这么大,存在本地我当然不在乎大一点,但是存在云端还要经常上传下载同步到手机我就觉得应该压缩一下了。各种截屏工具都有把图片放到剪贴板中的功能,所以我就想写个小程序对剪贴板中的图片做压缩。我想这个功能比较小众吧,就贴到这里,目的是抛砖引玉,希望大家能介绍能实现这个功能的更好的软件。