google webp格式图片批量转码

本文介绍了一个C++编写的工具,用于在多层目录下批量将WebP格式图片转换为PNG或保留原始格式,通过递归遍历和系统调用Google WebP工具实现。解决了文件夹包含空格和路径问题,并提供了使用dwebp命令的优化方法。

google webp格式图片批量转码

下载了大量图片,但是是webp格式。google提供的转码工具只能用dos命令一个个转码。所以写了个批量的。
代码主要涉及:
对文件夹文件遍历
对文件夹所有子目录遍历

#include<iostream>
#include<direct.h>
#include<io.h>
#include<string>
using namespace std;
int main(){
	void finddocu(string,int);
	char cway[500];
	_getcwd(cway,500);//获取程序所处绝对路径
	cout<<"  Welcome to webp converter 2.2"<<endl
		<<"  Author: Thirring"<<endl;
	for(bool flag=true;flag;){  //功能选择
		cout<<endl<<"option:"<<endl<<"1.all webp to png    2.all picture to webp    3.exit"<<endl;
		char in;
		cin>>in;
		switch(in){
		case '1':finddocu(cway,1);break;
		case '2':finddocu(cway,2);break;
		case '3':flag=false;break;
		default:cout<<endl<<endl<<"please input 1-3"<<endl;
		}
	}
	return 0;
}
void finddocu(string way,int ch){  //遍历所有子目录的递归;ch为选择的功能,way为当前路径
	void findfile(string,int);
	findfile(way,ch);	//对此目录的所有webp文件转码
	string all="\\*",findorder,docuname,nextway;
	findorder=way+all;  //查找范围变为子目录
	_finddata_t docu;
	long handle=_findfirst(findorder.c_str(),&docu);  //此时会获取当前目录第一个文件信息
	docuname=docu.name;
	if(docu.attrib & _A_SUBDIR&&docuname!="."&&docuname!=".."){  //判断是否为文件夹,且文件名不为.和..
		nextway=way+"\\"+docuname;finddocu(nextway,ch);  //是子目录则递归进入子目录,nextway为子目录绝对路径
	}
	for(;_findnext(handle,&docu)==0;){  //继续获取当前目录下一个文件信息
		docuname=docu.name;
		if(docu.attrib & _A_SUBDIR&&docuname!="."&&docuname!=".."){  //同上
			nextway=way+"\\"+docuname;finddocu(nextway,ch);  //同上
		}
	}
	_findclose(handle);
}
void findfile(string way,int ch){  //查找当前目录webp格式文件
	void trans(_finddata_t&,string,int,int);
	_finddata_t file;
	string findorder[6],wjpt[6]={"\\*.webp","\\*.jpg","\\*.png","\\*.tif","\\*.JPG","\\*.jpeg"};//jpeg要放在最后
	int num=6;
	for(int i=0;i<num;++i)findorder[i]=way+wjpt[i];
	for(int j=ch-1;j<num;++j){  //j为目标格式
	long handle=_findfirst(findorder[j].c_str(),&file);
	if(handle!=-1L){  //有满足条件的文件则继续查找
		trans(file,way,ch,j);
		for(;!_findnext(handle,&file);)trans(file,way,ch,j);
	}
	_findclose(handle);
	if(ch==1)break;
	}
}
void trans(_finddata_t & file,string way,int ch,int j){  //转码函数
	int i=0,n=5-ch+j/5;//此处5为==num-1
	string wjpt[6]={"webp","jpg","png","tif","JPG","jpeg"};
	for(;file.name[i]!='\0';++i);
	file.name[i-n]='\0';
	string filename=file.name,order;//获取目标文件文件名
	if(ch==1)order="dwebp \""+way+"\\"+filename+"webp\" "+"-o \""+way+"\\"+filename+"png\"";//修改此处可以改变输出图片格式
	if(ch==2)order="cwebp -q 100 \""+way+"\\"+filename+wjpt[j]+"\" "+"-o \""+way+"\\"+filename+"webp\"";
	system(order.c_str());//调用dos转码
	order=way+"\\"+filename+wjpt[j];
	remove(order.c_str());//删除已转码文件
}
#inlcude<direct.h>
char *getcwd( char *buffer, int maxlen );  //获取当前绝对路径
int chdir(const char *path);  //改变当前工作路径

struct _finddata_t{
	unsigned attrib;       //文件属性
	time_t time_create;    //文件创建时间
	time_t time_access;    //文件上一次访问时间
	time_t time_write;     //文件上一次修改时间
	_fsize_t size;         //文件字节数
	char name[_MAX_FNAME]; //文件名
};

文件属性是无符号整数,取值为相应的宏:
_A_ARCH(存档),
_A_SUBDIR(文件夹),
_A_HIDDEN(隐藏),
_A_SYSTEM(系统),
_A_NORMAL(正常),
_A_RDONLY(只读)。

函数:_findfirst、findnext和 _findclose

一、long _findfirst( char *filespec, struct _finddata_t fileinfo )
返回值:如果查找成功的话,将返回一个long型的唯一的查找用的句柄(就是一个唯一编号)。这个句柄将在_findnext函数中被使用。若失败,则返回-1。
参数:
filespec:标明文件的字符串,可支持通配符。比如:
.c,则表示当前文件夹下的所有后缀为C的文件。
fileinfo :这里就是用来存放文件信息的结构体的指针。这个结构体必须在调用此函数前声明,不过不用初始化,只要分配了内存空间就可以了。函数成功后,函数会把找到的文件的信息放入这个结构体中。

二、int _findnext( long handle, struct _finddata_t *fileinfo )
返回值:若成功返回0,否则返回-1。
参数:
handle:即由_findfirst函数返回回来的句柄。
fileinfo:文件信息结构体的指针。找到文件后,函数将该文件信息放入此结构体中。

三、int _findclose( long handle )
返回值:成功返回0,失败返回-1。
参数:
handle :_findfirst函数返回回来的句柄。

总结:
官方webp工具,用dos命令使用。如转换webp to png 命令:dwebp .\*.webp -o .\*.png
(工作路径在文件所处位置)
整体思路:获取各层目录中文件绝对路径,调用dwebp命令完成。
1.
Q:文件夹有空格造成路径有空格,而dos中空格为分隔符;因此不能正确输入路径
S:对文件路径加引号,会被dos识别为整体
2.
Q:webp工具两种使用方法:
a.转换dos工作路径到文件所在位置,再调用dwebp命令;c++代码中转换工作路径用int chdir(const char *path); 需#include<direct.h>
b.调用dwebp命令时使用绝对路径:dwebp “F:\01.webp” -o “F:\01.png”
S:由于涉及多层目录。调用_chdir()函数容易出错;选用b
3.
Q:C++如何输入dos命令
S:使用system();
4.
Q:如何获取各层目录绝对路径
S:C++查找指定的文件夹或者文件
C++遍历文件夹(包含子文件夹中的文件)

工具已上传:
google webp转码工具

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值