我正在尝试编写一个函数来确定目录中的文件是否为gif / bmp / png / jpg扩展名。现在我想我已经正确编写了我的代码,直到列出目录中的文件并以二进制模式打开它们。
现在,我正在努力弄清楚如何确定图像的扩展名。现在我只专注于写我的“bool isGif();” function ...要确定文件是否是使用二进制文件的.gif扩展名,文件的前6个字节将包含GIF87a或GIF89a。那么,为此,我会将文件的前六个字节读入一个数组,然后将它们与包含“GIF87a”或“GIF89a”的数组进行比较,对吗?
以下是我尝试对此进行编码。它给了我2个警告,但没有错误,它在程序中运行正常,但它从不输出一个消息,该目录包含一个gif,我知道它确实如此,因为我把它放在那里......
getDir();
ifstream fin;
_finddata_t a_file;
intptr_t dir_handle;
dir_handle = _findfirst("*.*", &a_file);
//if (dir_handle == -1)
//{
//return;
//}
while (_findnext(dir_handle, &a_file) == 0);
{
fin.open(a_file.name, ios::in | ios::binary);
if (!fin)
{
cout << endl << "Could not open the file."
<< " Attempting to open the next file." << endl;
return false;
}
else
{
cout << "Files opened successfully."
<< " Processing through the directory." << endl;
ifstream fl(a_file.name);
fl.seekg(0, ios::end);
size_t len = fl.tellg();
char *ret = new char[len];
fl.seekg(0, ios::beg);
fl.read(ret, len);
fl.close();
char arr1[6] = { 'G', 'I', 'F', 8, 7, 'a' };
char arr2[6] = { 'G', 'I', 'F', 8, 9, 'a' };
if (ret == arr1 || arr2 )
{
cout << a_file.name << " has a .gif extension" << endl;
return true;
}
}
}
好的,我想我现在已经接近了...这是对此问题很重要的更新/更改代码片段...我只是想尝试使用for循环来读取前6个字节到字符串,所以我可以比较这些位来确定它是否是一个gif,但我无法将字节输入字符串。
int i;
int comp1, comp2;
for (i = 0; i != 6; i++)
{
string gifStr;
fin.read((char*)&a_file, i);
gifStr(&a_file, i);
}
string gifStr1 = "GIF87a";
string gifStr2 = "GIF89a";
comp1 = strcmp( , gifStr1);
if (comp1 == 0)
{
cout << a_file.name << " has a .gif extension" << endl;
}
comp2 = strcmp( , gifStr2);
if (comp2 == 0)
{
cout << a_file.name << " has a .gif extension" << endl;
}
对不起,这个网站让我对这些回复和那些事情感到困惑......哈哈。
答案 0 :(得分:1)
你可以查找你想要的每种图像类型的幻数。然后比较它们(类似),如下面的..它只有一些神奇的数字..我在C ++ 0x第一次出现时写了这个out ..可能有更好的方法,但下面应该给出一个粗略的想法..
int ValidImage(std::uint8_t* ImageBytes)
{
const static std::vector<std::uint8_t> GIFBytesOne = { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 };
const static std::vector<std::uint8_t> GIFBytesTwo = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 };
const static std::vector<std::uint8_t> PNGBytes = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
const static std::vector<std::uint8_t> BMPBytes = { 0x42, 0x4D };
const static std::vector<std::uint8_t> JPGBytes = { 0xFF, 0xD8, 0xFF };
const static std::vector<std::uint8_t> JPEGBytes = { 0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20 };
const static std::vector<std::uint8_t> TIFFMonoChrome = { 0x0C, 0xED };
const static std::vector<std::uint8_t> TIFFOne = { 0x49, 0x20, 0x49 };
const static std::vector<std::uint8_t> TIFFTwo = { 0x49, 0x49, 0x2A, 0x00 };
const static std::vector<std::uint8_t> TIFFThree = { 0x4D, 0x4D, 0x00, 0x2A };
const static std::vector<std::uint8_t> TIFFFour = { 0x4D, 0x4D, 0x00, 0x2B };
const static std::vector<std::uint8_t> CompressedTGA = {0x0, 0x0, 0xA, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
const static std::vector<std::uint8_t> DeCompressedTGA = {0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
const static std::array<std::vector<std::uint8_t>, 13> All = {
GIFBytesOne, GIFBytesTwo, PNGBytes, BMPBytes,
JPGBytes, JPEGBytes, TIFFMonoChrome, TIFFOne,
TIFFTwo, TIFFThree, TIFFFour, CompressedTGA,
DeCompressedTGA
};
int I = 0;
for (const auto& it : All)
{
if (std::equal(it.begin(), it.end(), ImageBytes))
return I;
++I;
}
return -1;
}
然后:
std::fstream hFile(FilePath, std::ios::in | std::ios::binary);
if (!hFile.is_open())
{
throw std::invalid_argument("File Not Found.");
}
std::uint8_t Header[18] = {0};
hFile.read(reinterpret_cast<char*>(&Header), sizeof(Header));
hFile.seekg(0, std::ios::beg);
IMAGE_TYPE type = ValidImage(Header);
其中IMAGETYPE
定义为:
enum IMAGE_TYPE {GIF = 0, PNG, BMP, JPG, JPEG, TIFF, TGA};
答案 1 :(得分:0)
罪魁祸首在这里:
if (ret == arr1 || arr2 )
你无法测试像这样的char数组是否相等。此外 - 测试本身是不正确的。首先 - 如果可以这样检查 - 您必须将其更改为:
if (ret == arr1 || ret == arr2 )
然而,仍然无法做到这一点,你必须做以下其中一项:
ret
,arr1
和arr2
转换为std::string
strcmp
char
,循环从您的评论和编辑到问题,您在这里可以做的最好的事情是阅读strings。甚至可以查看一些documentation。
答案 2 :(得分:0)
以下代码的问题是它将整个文件加载到内存中,即使您只想检查几个字节。这很浪费,但留作练习。
ifstream fl(a_file.name);
fl.seekg(0, ios::end);
vector<char> ret(fl.tellg());
fl.seekg(0, ios::beg);
fl.read(&ret[0], ret.size());
fl.close();
static const vector<string> gif_ids = { "GIF87a", "GIF89a" };
bool is_gif = false;
for (const auto& id : gif_ids)
{
// check size first because the file may contain less data than the id
if (ret.size() >= id.size() && std::equal(id.begin(), id.end(), ret.begin()))
{
// it's a gif!
is_gif = true;
break;
}
}