I'm trying to use the Magick++ API (part of ImageMagick) for c++ and I've been looking around a while now and haven't seen that much documentation or examples on google. There's a lot of good documentation about it, but I can't find anything on how to use the ping() (not networking ping) function to return the size information of an image inside a c++ program. I've tried to make a blob object and use it like I've seen in the error.
I've seen a lot of the same general manual like:
http://web.mit.edu/graphics/share/ImageMagick/www/Magick++/Image.html#Image%20Attributes which is the same as http://www.imagemagick.org/Magick++/Image.html
I was looking at ping under "Image Manipulation Methods" and saw that it took a const Blob &blob_ as input. I tried doing the following, though I'm not really sure what I'm doing with ping(). I've got a lot of other stuff working, just can't figure this out.
#include <Magick++.h>
#include <iostream>
using namespace std;
using namespace Magick;
int main(int argc,char **argv)
{
InitializeMagick(*argv);
Image master("horse.jpg");
Image second = master;
// tried creating a blob (Binary Large OBject) per the error
Blob blob;
master.write ( &blob);
cout << blob.ping(&blob) << endl;
// also tried
// cout << master.ping() << endl;
// cout << master.ping( &blob) << endl;
return 0
}
I can't even find much in the way of examples for Magick++ stuff or ping.
test3.cpp:15:26: note: candidates are:
In file included from /usr/include/ImageMagick/Magick++.h:10:0,
from test3.cpp:1:
/usr/include/ImageMagick/Magick++/Image.h:501:21: note: void Magick::Image::ping(const string&)
void ping ( const std::string &imageSpec_ );
^
/usr/include/ImageMagick/Magick++/Image.h:501:21: note: candidate expects 1 argument, 0 provided
/usr/include/ImageMagick/Magick++/Image.h:507:21: note: void Magick::Image::ping(const Magick::Blob&)
void ping ( const Blob &blob_ );
^
/usr/include/ImageMagick/Magick++/Image.h:507:21: note: candidate expects 1 argument, 0 provided
So I guess ping returns void which it didn't say in the manual. I'm not even sure how I'd get values from it. Should I just take a look at the source code? Does anyone know where I could find more reading on this? Or is anyone familiar with Magick++. I'm sorry for being so clueless but google just isn't turning up much in the way of results for me about this.
Any help would be much appreciated!
The return type of ping is 'void' because it almost does the same as read. The ping method reads all the meta-data from the image but stops processing the image as soon as the part that contains the 'pixel data' is reached. You cannot read the 'pixel data' but you can get the columns() and rows() after the image has been 'pinged'. This information is also available in the documentation of Magick++ that can be found here: http://www.imagemagick.org/Magick++/Image.html.
Below is an example of how you can use the ping method:
#include <Magick++.h>
#include <iostream>
using namespace std;
using namespace Magick;
int main(int argc,char **argv)
{
InitializeMagick(*argv);
Image master;
master.ping("horse.jpg");
cout << master.columns() << "x" << master.rows() << endl;
return 0;
}
Related
I've been a C++ developer since it arrived. All was on windows, and I haven't touched it in about 6 years.
Now I'm trying to get an old code-base working using VS Code on my Mac. I'm using clang++ with c++17.
This problem is vexing; I've seen many other posts with the same issue, but the problem always seemed to be something in the code.
Note: this code worked fine with C++11 on Windows.
To simplify, I copied the code to execute right at the top of main. Here is is:
ifstream file("assets/textures/blocks.txt", ios::in);
if( file.is_open() ) {
string s;
getline(file, s); // <-- This line causes the error.
cout << s << endl;
}
As this code worked elsewhere, I assume I've got a setup or environment problem and am looking for hints towards what to check on.
Thank you for any help!
An update:
Thank you. I paired the program down and tried a few things. Here's the deal:
If I leave all my files to be compiled, but replace main.cpp with the below code, the cout line generates the same exception.
If I cull all the unused files, the code works.
Something in some other file is somehow breaking the stream code. I'm clueless.
#include <iostream>
#include <istream>
using namespace std;
int main() // int argc, char** argv)
{
cout << "Hello World" << endl;
}
I should add: this is a GLFW 3D game engine app. It does not subclass or interact with any stream in any way other than the most basic file read/write operations.
Some of this code may seem foreign to you since I make 3ds homebrew programs for fun but it's essentially the same but with extra lines of code you can put in. I'm trying to read a file called about.txt in a separate folder. I made it work when I put it in the same folder but i lost that file and then my partner said he wanted it in Scratch3ds-master\assets\english\text and not in Scratch3ds-master\source I keep getting the error I coded in. I'm new to stack-overflow so this might be too much code but well here's the code:
#include <fstream>
#include <string>
#include <iostream>
int main()
{
// Initialize the services
gfxInitDefault();
consoleInit(GFX_TOP, NULL);
int version_major;
int version_minor;
int version_patch;
version_major = 0;
version_minor = 0;
version_patch = 2;
printf("This is the placeholder for Scratch3ds\n\n");
std::ifstream about_file;
about_file.open("../assets/english/text/about.txt");
if (about_file.fail())
{
std::cerr << "file has failed to load\n";
exit(1);
}
Chance are that you're using devkitpro packages. And chances are that the devkitpro team provide an equivalent of the NDS 'ARGV protocol' for 3DS programming. In which case, if you use
int main(int argc, char* argv[]);
you should have the full path to your executable in argv[0] if argc is non-zero.
https://devkitpro.org/wiki/Homebrew_Menu might help.
Your program has no a priori knowledge of what sort of arguments main() should receive, and in your question, you're using a main function that receives no argument at all.
Established standard for C/C++ programming is that main() will receive an array of constant C strings (typically named argv for arguments values) and the number of valid entries in that array (typically named argc for count). If you replace your original code with
#include <fstream>
#include <string>
#include <iostream>
int main(int argc, char* argv[])
{
// Initialize the services
// ... more code follows
then you're able to tell whether you received argument by testing argc > 0 and you'll be able to get these arguments values with argv[i].
With homebrew development, it is unlikely that you can pass arguments such as --force or --directory=/boot as on typical command-line tools, but there is one thing that is still useful: the very first entry in argv is supposed to be a full path for the running program. so you're welcome to try
std::cerr << ((argc > 0) ? argv[0] : "<no arguments>");
and see what you get.
I am using this open source software for working with Sick Lidar Devices:
https://github.com/rhuitl/sicktoolbox/tree/master/trunk/c%2B%2B/drivers/lms5xx/sicklms5xx
and this documentation which provides information on the data:
https://www.sick.com/media/docs/7/27/927/Technical_information_Telegram_Listing_Ranging_sensors_LMS1xx_LMS5xx_TiM5xx_NAV310_LD_OEM15xx_LD_LRS36xx_en_IM0045927.PDF
I am trying to use the C++ implementation to parse already written files in the "CoLa B" format from SickLMS5xx, mentioned in said documentation. However, this toolbox appears to have been written to deal with the device directly, and not files that are outputted from it (like what I am working with).
It appears I can use the functions in the SickLMS5xxMessage (ParseMessage() etc.) to achieve what I want. I made a main method to interract with this class (and it's SickMessage() superclass) like so:
#include <iostream>
#include <fstream>
#include <boost/thread/thread.hpp>
#include "SickLMS5xxMessage.cc"
void run() {
SickLMS5xxMessage msg(uint8_t * const telegramFileBuffer[]);
std::ifstream telegramFile("MMS21_01");
if(telegramFile.is_open()) {
uint8_t telegramFileBuffer[msg.GetMessageLength()];
for(int i = 0; i < msg.GetMessageLength(); ++i) {
telegramFile >> telegramFileBuffer[i];
}
}
msg.Print();
}
int main (int argc, char** argv) {
run();
return (0);
}
But it doesn't appear to work properly, as it cannot recognise the GetMessageLength() and Print() functions from SickLMS5xxMessage, and gives me an unresolved method error?
Maybe it's an error with my C++ coding (because I come from a Java background and so C++ is still relatively new to me).
Any help will be appreciated though, thank you :)
I'm following some C++ tutorials and have started experimenting with structures, however a test structure I built is not behaving as intended. I have tried running it a few times and all it outputs is (11db), and when I try rerunning it I get a window saying that the product is already running.
Here is the code...
#include <iostream>
using namespace std;
int main(){
struct Address {
int streetNum;
string streetName;
};
Address myHouse;
myHouse.streetNum = 911;
myHouse.streetName = "Inverness Street";
cout << myHouse.streetName << endl;
return 0;
}
I would expect the output to be "Inverness Street". Why am I getting an error instead?
EDIT ** Bonus points for anyone who can tell me how to remove a missing file warning? I removed a useless file that was created as a means to find my way around creating different types of files, but since I deleted it I have had a warning in the file that it once shared a folder with.
I know there's been a handful of questions regarding std::ifstream::open(), but the answers didn't solve my problem. Most of them were specific to Win32, and I'm using SDL, not touching any OS-specific functionality (...that's not wrapped up into SDL).
The problem is: std::ifstream::open() doesn't seem to work anymore since I've switched from Dev-C++ to Code::Blocks (I've been using the same MinGW-GCC back-end with both), and from Windows XP to Vista. (It also works perfectly with OS X / xcode (GCC back-end).)
My project links against a static library which #includes <string>, <iostream>, <fstream> and <cassert>, then a call is made to functionality defined in the static library, which in turn calls std::ifstream::open() (this time, directly). Following this, the stream evaluates to false (with both the implicit bool conversion operator and the good() method).
Code:
#include "myStaticLibrary.hpp"
int main(int argc, char **argv)
{
std::string filename("D:/My projects/Test/test.cfg");
std::cout << "opening '" << filename << "'..." << std::endl;
bool success(false);
// call to functionality in the static library
{
std::ifstream infile(filename.c_str());
success = infile.good();
// ...
}
// success == false;
// ...
return 0;
}
stdcout.txt says:
opening 'D:/My projects/Test/test.cfg'...
When I open stdcout.txt, and copy-paste the path with the filename into Start menu / Run, the file is opened as should be (I'm not entirely sure how much of diagnostic value this is though; also, the address is converted to the following format: file:///D:/My%20projects/test/test.cfg).
I've also tried substituting '/'s with the double backslash escape sequence (again, slashes worked fine before), but the result was the same.
It is a debug version, but I'm using the whole, absolute path taken from main()'s argv[0].
Where am I going wrong and what do I need to do to fix it?
Please create a minimal set that recreates the problem. For example, in your code above there's parsing of argv and string concatentation, which do not seem like a necessary part of the question. A minimal set would help you (and us) see exactly what's going wrong, and not be distracted by questions like "what's GetPath()?".
Try to do this instead of assert(infile.good()):
assert(infile);
I have overseen the importance of the fact that the function in question has close()d the stream without checking if it is_open().
The fact that it will set the stream's fail_bit (causing it to evaluate to false) was entirely new to me (it's not that it's an excuse), and I still don't understand why did this code work before.
Anyway, the c++ reference is quite clear on it; the problem is now solved.
The following code:
#include <string>
#include <iostream>
#include <fstream>
#include <assert.h>
using namespace std;;
int main(int argc, char **argv)
{
std::string filename("D:/My projects/Test/test.cfg");
std::cout << "opening '" << filename << "'..." << std::endl;
std::ifstream infile(filename.c_str());
assert(infile.good()); // fails
return 0;
}
works fine on my Windows system using MinGW g++ 4.4.0, if I create the required directory structure. Does the file test.cfg actually exist? If you are opening a stream for input, it wioll fail if the file is not there.
Edit: To remove any DevC++ to CB issues:
build using command line only
make sure you rebuild the static library too