I would like to load image to my application, but I have an error:
http://img510.imageshack.us/img510/5814/blad07864.png
This is a code of this application:
#include <stdio.h>
#include <stdlib.h>
#undef _UNICODE
#include "il.h"
#pragma comment( lib, "DevIL.lib" )
// Wow. DevIL is amazing.
// From http://gpwiki.org/index.php/DevIL:Tutorials:Basics
// The library consists of three sub-libraries:
// * IL - main DevIL library. It allows you to load and save images to files. Every function in this library have 'il' prefixed to their name.
// * ILU - this library contains functions for altering images. Every function in this library have 'ilu' prefixed to their name.
// * ILUT - this library connects DevIL with OpenGL. Every function in this library have 'ilut' prefixed to their name.
int main()
{
ilInit();
printf("DevIL has been initialized\n");
// Loading an image
ILboolean result = ilLoadImage( "tex1.png" ) ;
if( result == true )
{
printf("the image loaded successfully\n");
}
else
{
printf("The image failed to load\n" ) ;
ILenum err = ilGetError() ;
printf( "the error %d\n", err );
printf( "string is %s\n", ilGetString( err ) );
}
int size = ilGetInteger( IL_IMAGE_SIZE_OF_DATA ) ;
printf("Data size: %d\n", size );
ILubyte * bytes = ilGetData() ;
for( int i = 0 ; i < size; i++ )
{
// see we should see the byte data of the image now.
printf( "%d\n", bytes[ i ] );
}
}
I found code from this site: http://bobobobo.wordpress.com/2009/03/02/how-to-load-a-png-image-in-c/
Can you help me?
According to this post, 1290 means the image path wasn't found. Try using an absolute file path and see if it can load then.
Related
I am using pHash and that library uses libpng. I am having issues running my program because libpng fails loading a PNG file.
Version of libpng: 1.4.19
Platform: Windows 10
Environment: Visual Studio 2015
Trivial
Just if you came up with the following questions...
Is the path to image correct? Yes
Is the image a valid PNG file? Yes
Code details
Library pHash uses CImg, the version of CImg they are using is a bit old I think:
#define cimg_version 148 // In CImg.h
I have debugged the library and the problems occurs in CImg.h (contained in the pHash VC++ project):
CImg<T>& _load_png(std::FILE *const file, const char *const filename) {
if (!file && !filename)
throw CImgArgumentException(_cimg_instance
"load_png() : Specified filename is (null).",
cimg_instance);
// Open file and check for PNG validity
if (Buffer) strcat(Buffer, "Checking PNG availability\r\n");
const char *volatile nfilename = filename; // two 'volatile' here to remove a g++ warning due to 'setjmp'.
std::FILE *volatile nfile = file?file:cimg::fopen(nfilename,"rb");
unsigned char pngCheck[8] = { 0 };
cimg::fread(pngCheck,8,(std::FILE*)nfile);
if (png_sig_cmp(pngCheck,0,8)) {
if (!file) cimg::fclose(nfile);
throw CImgIOException(_cimg_instance
"load_png() : Invalid PNG file '%s'.",
cimg_instance,
nfilename?nfilename:"(FILE*)");
}
// Setup PNG structures for read
png_voidp user_error_ptr = 0;
png_error_ptr user_error_fn = 0, user_warning_fn = 0;
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,user_error_ptr,user_error_fn,user_warning_fn);
if (!png_ptr) { // <-- PROBLEM HERE
if (!file) cimg::fclose(nfile);
throw CImgIOException(_cimg_instance
"load_png() : Failed to initialize 'png_ptr' structure for file '%s'.",
cimg_instance,
nfilename?nfilename:"(FILE*)");
...
}
The snippet shows the first part of CImg<T>& _load_png(std::FILE *const file, const char *const filename) which is called by the CImg library used by pHash.
Runtime issue
The code compiles fine but I get this error at runtime which I can see in the debugger:
CImgIOException: Failed to initialize 'png_ptr'...
In the point indicated in the code. I don't know why, it fails loading the image. The failure occurs when calling png_create_read_struct in CImg.h. That code is a bit obscure as defined through preprocessor directives. It is not clear why it is failing.
Any ideas?
Either if you are including libpng yourself or if another library is including and using libpng there are a few things to be aware of.
Which ever version of Visual Studio you are using, the libpng (dll or lib) files must be built from the same version of Visual Studio that your solution is linking against.
The platform you are using 32bit or 64bit is of concern.
Project settings when building the png library must match the build types of your current project. (Code Generation -> Runtime Library) must match. Your character set should match as well.
It is a little to difficult to tell what exactly is causing the problem but these are a few things to have a look at.
One thing I would suggest is to go to the website that provides the newest version of libpng and download it. Set a folder on your computer and create "system environment variable through windows" to point to your library. Open the solution to this library in the current version of VS you are using, build it out for both a static lib and dynamic lib (two different solutions) and build them both out for 32 bit and 64 bit saving the generated files into separated folders. Then go into the other library that depends on this and try to switch the dlls or libs and link against the new ones if possible. Also the other 3rd party library you should try to open its solution in the same version of VS and try to do a clean build from there. Then make sure you link everything properly. You may have to also modify the props file.
EDIT
I am not familiar with pHash or CImg, but I am familiar with libpng.
Here is a function in one of my projects to load in a png into a texture structure. Now this is a part of a class object that relies on many other classes, but you should be able to see from this snippet that I am successfully using 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
Looking through the source code for png_create_read_struct_2(), there are only 2 failure modes: inability to allocate memory, which is unlikely to be the problem, and a library version conflict.
If you are using a precompiled build of the pHash library, you must ensure that the copy of the libpng DLL that gets linked dynamically at runtime is the same version of the library that pHash was compiled against. The latest Windows build on pHash.org ships with libpng12.dll in the "Release" subdirectory, which is probably incompatible the version that you mentioned in the question, namely 1.4.19.
If you are building pHash from source, make sure that the libpng include files that are being used in your build process match the version being loaded at runtime.
If you're unsure exactly which DLLs are being loaded at runtime, the surest way I know to determine it would be to use Process Monitor.
I want to copy the framebuffer to an LCD display on my raspberry pi running raspbian. To do so I am using the following code:
#include <stdio.h>
#include <stdlib.h>
#include "RAIO8870.h"
#include <bcm_host.h>
int main(int argc, char **argv)
{
DISPMANX_DISPLAY_HANDLE_T main_display_handle;
DISPMANX_RESOURCE_HANDLE_T screen_resource_handle;
VC_RECT_T rectangle;
int ret;
uint32_t image_prt;
uint16_t image[ PICTURE_PIXELS ];
bcm_host_init();
if ( !bcm2835_init() )
return ( -1 );
TFT_init_board();
TFT_hard_reset();
RAIO_init();
RAIO_SetBacklightPWMValue( 255 );
uint32_t screen=0;
printf("Open display[%i]...\n", screen );
// open main framebuffer device
main_display_handle = vc_dispmanx_display_open( screen );
if ( !main_display_handle )
{
printf("\n Unable to open display %i Handle: %i",screen,main_display_handle);
return( -1 );
}
The program always exits in the if condition, as vc_dispmanx_display_open does return 0. I was not able to find any documentation about this function.
So why does it return an invalid handle and how to avoid this?
Deal all,
I need to decode an animated gif format picture into some bitmap files in MFC2010. Is there any library to decode a gif picture? I cannot use GDIPlus because the program has to run on windows XP. I do appreciate if someone provides me with a library, Activex, dll or anything similar.
Many Thanks,
Shervin Zargham
It's pretty simple using ImageMagick's C++ API (Magick++) :
/* list of Image to store the GIF's frames */
std::vector<Magick::Image> imageList;
/* read all the frames of the animated GIF */
Magick::readImages( &imageList, "animated.gif" );
/* optionnally coalesce the frame sequence depending on the expected result */
Magick::coalesceImages( &imageList, imageList.begin(), imageList.end());
/* store each frame in a separate BMP file */
for(unsigned int i = 0; i < imageList.size(); ++i) {
std::stringstream ss;
ss << "frame" << i << ".bmp";
imageList[i].write(ss.str());
}
WIC (included in Vista, available for XP) offers CLSID_WICGifDecoder, a COM component.
Try this using ImageMagick's C++ API (Magick++) ,tested on VS210:
#include <Magick++.h>
#include <string>
#include <iostream>
#include <list>
using namespace std;
using namespace Magick;
void kk(char * nombre, char *ext)
{
/* list of Image to store the GIF's frames */
std::list<Magick::Image> imageList;
/* read all the frames of the animated GIF */
Magick::readImages( &imageList, nombre );
/* compone las diferencias para obtener los cuadros reales */
Magick::coalesceImages(&imageList,imageList.begin( ),imageList.end( ));
/* store each frame in a separate BMP file */
list <Magick::Image>::iterator it;
int i=1;
for ( it = imageList.begin( ); it != imageList.end( ); it++ , i++)
{
std::string name = "frame" + to_string((_Longlong)(i)) + ext ;
it->write(name);
}
}
int main( int /*argc*/, char ** argv)
{
// Initialize ImageMagick install location for Windows
InitializeMagick(*argv);
try {
kk("luni0.gif", ".png"); // using ".bmp", ".jpg", ".png", OK
return 0;
}
catch( exception &error_ )
{
cout << "Caught exception: " << error_.what() << endl;
return 1;
}
}
It's been a long time, but I recall once using OleLoadPicture to open GIF and PNG files on old versions of Windows, though the documentation seems to suggest that it's only for BMP, ICO, and WMF.
I am doing a project on object detection in OpenCV using haar training. I have to mark, in an image, all the places where the object is present. So, I need a code which opens each image so that I can mark the regions.
Similar to the one here:
#include <opencv/cv.h>
#include <opencv/cvaux.h>
#include <opencv/highgui.h>
// for filelisting
#include <stdio.h>
#include <sys/io.h>
// for fileoutput
#include <string>
#include <fstream>
#include <sstream>
#include <dirent.h>
#include <sys/types.h>
using namespace std;
IplImage* image=0;
IplImage* image2=0;
//int start_roi=0;
int roi_x0=0;
int roi_y0=0;
int roi_x1=0;
int roi_y1=0;
int numOfRec=0;
int startDraw = 0;
char* window_name="<SPACE>add <B>save and load next <ESC>exit";
string IntToString(int num)
{
ostringstream myStream; //creates an ostringstream object
myStream << num << flush;
/*
* outputs the number into the string stream and then flushes
* the buffer (makes sure the output is put into the stream)
*/
return(myStream.str()); //returns the string form of the stringstream object
};
void on_mouse(int event,int x,int y,int flag, void *param)
{
if(event==CV_EVENT_LBUTTONDOWN)
{
if(!startDraw)
{
roi_x0=x;
roi_y0=y;
startDraw = 1;
} else {
roi_x1=x;
roi_y1=y;
startDraw = 0;
}
}
if(event==CV_EVENT_MOUSEMOVE && startDraw)
{
//redraw ROI selection
image2=cvCloneImage(image);
cvRectangle(image2,cvPoint(roi_x0,roi_y0),cvPoint(x,y),CV_RGB(255,0,255),1);
cvShowImage(window_name,image2);
cvReleaseImage(&image2);
}
}
int main(int argc, char** argv)
{
char iKey=0;
string strPrefix;
string strPostfix;
string input_directory;
string output_file;
if(argc != 3) {
fprintf(stderr, "%s output_info.txt raw/data/directory/\n", argv[0]);
return -1;
}
input_directory = argv[2];
output_file = argv[1];
/* Get a file listing of all files with in the input directory */
DIR *dir_p = opendir (input_directory.c_str());
struct dirent *dir_entry_p;
if(dir_p == NULL) {
fprintf(stderr, "Failed to open directory %s\n", input_directory.c_str());
return -1;
}
fprintf(stderr, "Object Marker: Input Directory: %s Output File: %s\n", input_directory.c_str(), output_file.c_str());
// init highgui
cvAddSearchPath(input_directory);
cvNamedWindow(window_name,1);
cvSetMouseCallback(window_name,on_mouse, NULL);
fprintf(stderr, "Opening directory...");
// init output of rectangles to the info file
ofstream output(output_file.c_str());
fprintf(stderr, "done.\n");
while((dir_entry_p = readdir(dir_p)) != NULL)
{
numOfRec=0;
if(strcmp(dir_entry_p->d_name, ""))
fprintf(stderr, "Examining file %s\n", dir_entry_p->d_name);
/* TODO: Assign postfix/prefix info */
strPostfix="";
//strPrefix=input_directory;
strPrefix=dir_entry_p->d_name;
//strPrefix+=bmp_file.name;
fprintf(stderr, "Loading image %s\n", strPrefix.c_str());
if((image=cvLoadImage(strPrefix.c_str(),1)) != 0)
{
// work on current image
do
{
cvShowImage(window_name,image);
// used cvWaitKey returns:
// <B>=66 save added rectangles and show next image
// <ESC>=27 exit program
// <Space>=32 add rectangle to current image
// any other key clears rectangle drawing only
iKey=cvWaitKey(0);
switch(iKey)
{
case 27:
cvReleaseImage(&image);
cvDestroyWindow(window_name);
return 0;
case 32:
numOfRec++;
printf(" %d. rect x=%d\ty=%d\tx2h=%d\ty2=%d\n",numOfRec,roi_x0,roi_y0,roi_x1,roi_y1);
//printf(" %d. rect x=%d\ty=%d\twidth=%d\theight=%d\n",numOfRec,roi_x1,roi_y1,roi_x0-roi_x1,roi_y0-roi_y1);
// currently two draw directions possible:
// from top left to bottom right or vice versa
if(roi_x0<roi_x1 && roi_y0<roi_y1)
{
printf(" %d. rect x=%d\ty=%d\twidth=%d\theight=%d\n",numOfRec,roi_x0,roi_y0,roi_x1-roi_x0,roi_y1-roi_y0);
// append rectangle coord to previous line content
strPostfix+=" "+IntToString(roi_x0)+" "+IntToString(roi_y0)+" "+IntToString(roi_x1-roi_x0)+" "+IntToString(roi_y1-roi_y0);
}
else
//(roi_x0>roi_x1 && roi_y0>roi_y1)
{
printf(" hello line no 154\n");
printf(" %d. rect x=%d\ty=%d\twidth=%d\theight=%d\n",numOfRec,roi_x1,roi_y1,roi_x0-roi_x1,roi_y0-roi_y1);
// append rectangle coord to previous line content
strPostfix+=" "+IntToString(roi_x1)+" "+IntToString(roi_y1)+" "+IntToString(roi_x0-roi_x1)+" "+IntToString (roi_y0-roi_y1);
}
break;
}
}
while(iKey!=66);
{
// save to info file as later used for HaarTraining:
// <rel_path>\bmp_file.name numOfRec x0 y0 width0 height0 x1 y1 width1 height1...
if(numOfRec>0 && iKey==66)
{
//append line
/* TODO: Store output information. */
output << strPrefix << " "<< numOfRec << strPostfix <<"\n";
cvReleaseImage(&image);
}
else
{
fprintf(stderr, "Failed to load image, %s\n", strPrefix.c_str());
}
}
}}
output.close();
cvDestroyWindow(window_name);
closedir(dir_p);
return 0;
}
I ran the above code using Visual Studio 10.
When I run the above code it is opening the command window loading all the images (a new named window is also getting opened but getting but it is not staying for me to select the region) and then closing.
When I ran it using start without debugging option in VS10 it is I could see this:
Examining file img (6).jpeg
Loading image img (6).jpeg
Examining file img (6).JPG
Loading image img (6).JPG
Examining file img (7).jpeg
Loading image img (7).jpeg
Examining file img (7).jpg
Loading image img (7).jpg
Examining file img (8).jpeg
Loading image img (8).jpeg
Examining file img (8).jpg
Loading image img (8).jpg
Examining file img (9).jpeg
Loading image img (9).jpeg
Examining file img (9).jpg
Loading image img (9).jpg
Examining file img 1.jpeg
Loading image img 1.jpeg
the object marker fails and cannot load the image
I think that it is skipping the:
if((image=cvLoadImage(strPrefix.c_str(),1)) != 0){.....}
part of the code
There are few currently available object marking tools for Haar training. I use the tool in this link. Its perfectly worked for me. If you want to build your own tool please follow this tutorial. Any way I think when it comes to Haar training, it is waste of time to develop tools to capture coordinates because there are currently available tools for those and it is not the main goal of Haar training. Because Haar training takes more time to train and create cascade XML file. So its better to focus on training.
Does anyone know of a library which will assist in decoding cron style timings, i.e.
30 7 * * 1-5
Which is 7:30am every Monday, Tuesday, Wednesday, Thursday, Friday.
M.
There is a library for PHP, Perl but I never saw one for C++.
The good thing is that Cron's source is freely available and you can reuse its code to parse entries in the cron format.
The entry data structure is defined in "cron.h" file:
typedef struct _entry {
struct _entry *next;
uid_t uid;
gid_t gid;
char **envp;
char *cmd;
bitstr_t bit_decl(minute, MINUTE_COUNT);
bitstr_t bit_decl(hour, HOUR_COUNT);
bitstr_t bit_decl(dom, DOM_COUNT);
bitstr_t bit_decl(month, MONTH_COUNT);
bitstr_t bit_decl(dow, DOW_COUNT);
int flags;
#define DOM_STAR 0x01
#define DOW_STAR 0x02
#define WHEN_REBOOT 0x04
#define MIN_STAR 0x08
#define HR_STAR 0x10
} entry;
And there are two functions you need from "entry.c" file (too large to post code here):
void free_entry (e);
entry *load_entry (file, error_func, pw, envp);
You can compile those files into a shared library or object files and use directly in your project.
This is an example of getting cron source code in Debian (Ubuntu):
apt-get source cron
You can also download it from http://cron.sourcearchive.com/
For those that wish to achieve the same goal as #ScaryAardvark
Dependency:
http://cron.sourcearchive.com/downloads/3.0pl1/cron_3.0pl1.orig.tar.gz
Build:
gcc -o main main.c cron-3.0pl1.orig/entry.c cron-3.0pl1.orig/env.c
cron-3.0pl1.orig/misc.c -I cron-3.0pl1.orig
Source:
#include <pwd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <uuid/uuid.h>
#define MAIN_PROGRAM 1
#include "cron-3.0pl1.orig/cron.h"
void error_handler( char* message )
{
fprintf( stderr, "Error: %s\n", message );
}
void print_entry( const entry* e )
{
fprintf( stdout, "uid: %i\n", e->uid );
fprintf( stdout, "gid: %i\n", e->gid );
fprintf( stdout, "command: %s\n", e->cmd);
//etc...
}
int main( int argc, char** argv, char** envp )
{
const char* filename = "crontab";
const char* username = "bcrowhurst";
//Retreive Crontab File
FILE *file = fopen( filename, "r" );
if ( file == NULL )
{
error_handler( strerror( errno ) );
return EXIT_FAILURE;
}
//Retreive Password Entry
struct passwd *pw = getpwnam( username );
if ( pw == NULL )
{
error_handler( strerror( errno ) );
return EXIT_FAILURE;
}
//Read Entry
entry *e = load_entry( file, &error_handler, pw, envp );
if ( e == NULL )
{
error_handler( "No entry found!" );
return EXIT_FAILURE;
}
print_entry( e );
//Clean-up
fclose( file );
free_entry( e );
return EXIT_SUCCESS;
}
Example Crontab
#yearly /home/bcrowhurst/annual-process
*/10 * * * * /home/bcrowhurst/fschk