Ответ 1
Если вы включаете libpng самостоятельно или если в библиотеку включена и используется libpng, вам нужно знать несколько вещей.
- Какую версию Visual Studio вы используете, файлы libpng (dll или lib) должны быть созданы из той же версии Visual Studio, с которой связано ваше решение.
- Вы занимаетесь платформой, использующей 32-битную или 64-разрядную версию.
- Параметры проекта при создании библиотеки png должны соответствовать типам сборки вашего текущего проекта. (Генерация кода → Библиотека времени выполнения) должна совпадать. Ваш набор символов должен совпадать.
Немного сложно сказать, что именно вызывает проблему, но это несколько вещей, на которые нужно обратить внимание.
Одна вещь, которую я хотел бы предложить, - перейти на веб-сайт, который предоставляет новейшую версию libpng и загрузить ее. Установите папку на своем компьютере и создайте "переменную системной среды через окна", чтобы указать на вашу библиотеку. Откройте решение этой библиотеки в текущей версии VS, которую вы используете, создайте ее как для статической lib, так и для динамической библиотеки (два разных решения) и создайте их для 32-битного и 64-битного сохранения сгенерированных файлов в отдельные папки, Затем перейдите в другую библиотеку, которая зависит от этого, и попытайтесь переключить dlls или libs и связать их с новыми, если это возможно. Также в третьей сторонней библиотеке вы должны попытаться открыть свое решение в той же версии VS и попытаться сделать чистую сборку оттуда. Затем убедитесь, что вы все правильно свяжете. Возможно, вам придется изменить файл реквизита.
ИЗМЕНИТЬ
Я не знаком с pHash или CImg, но я знаком с libpng.
Вот функция в одном из моих проектов для загрузки в png в структуру текстуры. Теперь это часть объекта класса, которая опирается на многие другие классы, но вы должны уметь видеть из этого фрагмента, что я успешно использую libpng.
// ----------------------------------------------------------------------------
// loadPng()
bool TextureFileReader::loadPng( Texture* pTexture ) {
struct PngFile {
FILE* fp;
png_struct* pStruct;
png_info* pInfo;
// --------------------------------------------------------------------
PngFile() :
fp( NULL ),
pStruct( NULL ),
pInfo( NULL )
{} // PngFile
// --------------------------------------------------------------------
~PngFile() {
if ( NULL != fp ) {
fclose( fp );
}
if ( NULL != pStruct ) {
if ( NULL != pInfo ) {
png_destroy_read_struct( &pStruct, &pInfo, NULL );
} else {
png_destroy_read_struct( &pStruct, NULL, NULL );
}
}
} // ~PngFile
} png;
// Error Message Handling
std::ostringstream strStream;
strStream << __FUNCTION__ << " ";
if ( fopen_s( &png.fp, m_strFilenameWithPath.c_str(), "rb" ) != 0 ) {
strStream << "can not open file for reading";
throwError( strStream );
}
// Test If File Is Actually A PNG Image
const int NUM_HEADER_BYTES = 8;
png_byte headerBytes[NUM_HEADER_BYTES];
// Read The File Header
if ( fread( headerBytes, 1, NUM_HEADER_BYTES, png.fp ) != NUM_HEADER_BYTES ) {
strStream << "error reading header";
return false;
}
// Test Header
if ( png_sig_cmp( headerBytes, 0, NUM_HEADER_BYTES ) != 0 ) {
return false; // Not A PNG FILE
}
// Init PNG Read Structure - Test PNG Version Compatibility
png.pStruct = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
if ( NULL == png.pStruct ) {
strStream << "can not create struct for PNG file";
throwError( strStream );
}
// Init PNG Info Structure - Allocate Memory For Image Info
png.pInfo = png_create_info_struct( png.pStruct );
if ( NULL == png.pInfo ) {
strStream << "can not create info for PNG file";
throwError( strStream );
}
// Prepare For Error Handling
if ( setjmp( png_jmpbuf( png.pStruct ) ) ) {
strStream << "can not init error handling for PNG file";
throwError( strStream );
}
// Tell libPng Where The File Data Is
png_init_io( png.pStruct, png.fp );
// Tell libPng That You Have Already Read The Header Bytes
png_set_sig_bytes( png.pStruct, NUM_HEADER_BYTES );
// Read Image Data From The File
png_read_png( png.pStruct, png.pInfo, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_GRAY_TO_RGB, NULL );
// Show Image Attributes
png_byte colorType = png_get_color_type( png.pStruct, png.pInfo );
switch( colorType ) {
case PNG_COLOR_TYPE_RGB:
case PNG_COLOR_TYPE_RGBA: {
break;
}
default: {
strStream << "PNG is saved in an unsupported color type (" << colorType << ")";
throwError( strStream );
}
}
unsigned uHeight = png_get_image_height( png.pStruct, png.pInfo );
unsigned uBytesPerRow = png_get_rowbytes( png.pStruct, png.pInfo );
if ( 0 == uHeight || 0 == uBytesPerRow ) {
strStream << "invalid image size. Height(" << uHeight << "), Bytes per row(" << uBytesPerRow << ")";
throwError( strStream );
}
// Make Room For All Pixel Data
unsigned uTotalNumBytes = uHeight * uBytesPerRow;
pTexture->vPixelData.resize( uTotalNumBytes );
// Get All Pixel Data From PNG Image
png_bytepp ppPixelRow = png_get_rows( png.pStruct, png.pInfo );
for ( unsigned int r = 0; r < uHeight; ++r ) {
memcpy( &pTexture->vPixelData[ uBytesPerRow * ( uHeight - 1 - r ) ], ppPixelRow[r], uBytesPerRow );
}
// Store Other Values In Texture
pTexture->uWidth = png_get_image_width( png.pStruct, png.pInfo );
pTexture->uHeight = uHeight;
pTexture->hasAlphaChannel = ( colorType == PNG_COLOR_TYPE_RGBA );
return true;
} // loadPng