I want to make an annotation in a gif image using ImageMagick and specifically Magick++, the code is quite simple, but the output image has artifacts in the text, if the gif does not move, then the artifacts do not appear, here:
here is the code itself, very simple:
int main()
{
InitializeMagick(nullptr);
list<Image> *imageList = new list<Image>();
try {
readImages(imageList, "source.gif" );
}
catch( exception &error_ )
{
cout << "Caught exception: " << error_.what() << endl;
return 1;
}
for(Image &i : *imageList) {
i.fontPointsize(36);
i.font("helvetica-bold");
i.fillColor(Color("white"));
i.fontStyle(MagickCore::ObliqueStyle);
i.annotate("why are you lagging", SouthGravity);
}
writeImages(imageList->begin(), imageList->end(), "/home/deymos/GifnText/n.gif");
return 0;
I tried to save the list of images as png and this is what I saw when the movement on the gif started:
is it possible to fix it, or is it a bug?
If this cannot be fixed, maybe there are similar tools with which I can implement text on gifs? or at least a library that can disassemble gifs into images and fold, I can do the rest with qt, tnx.
Related
I'm making my own text editor with C++ and the SFML multi-media library. I'm now trying to implement a user interface so users can interact and select documents to edit. I have this function:
std::vector<sf::Text> Menu::GetAllTextOptions(TextHandler& handler, sf::Font font) {
std::vector<TextDocument>* all_available_documents = handler.GetTextDocuments();
std::vector<sf::Text> menu_text_options;
for (int i = 0; i < all_available_documents->size(); i++) {
sf::Text text;
text.setFont(font);
text.setString(std::to_string(i) + ") " + all_available_documents->at(i).GetDocumentName() + '\n');
menu_text_options.push_back(text);
}
return menu_text_options;
}
What this is supposed to do is collect all of the names of already existing text documents in a path that I have specified (the code behind gathering the TextDocument objects works perfectly). It then makes a text object, sets a font to it and sets the string to the name of the document. When I std::cout the count of the vector, it displays correctly the amount of documents that exist.
I then have a function that is supposed to go through the vector of texts and draw all of them, so they can be later displayed:
// ACCESS VIOLATION ERROR
void Menu::DrawAllOptions(sf::RenderWindow& window, std::vector<sf::Text>&
menu_text_options) {
std::cout << menu_text_options.size() << " is the current size " << std::endl;
try {
for (int i = 0; i < menu_text_options.size(); i++) {
// EXCEPTION THROWN HERE
window.draw(menu_text_options.at(i));
}
}
catch (const std::exception& ex) {
std::cout << "Exception: " << ex.what() << '\n';
}
}
Finally, I have the main loop where everything comes into place:
std::string Menu::MenuControl(TextHandler& handler) {
Utility utility;
sf::RenderWindow menu_window(sf::VideoMode(800, 600), "Menu");
sf::Color backgroundColor(0, 32, 63);
sf::Event event;
sf::Font font;
sf::Text menu_text;
utility.CheckFontLoaded(font, "../8bitfont.ttf");
std::vector<sf::Text> menu_text_options = GetAllTextOptions(handler, font);
int menu_counter = 0; // Start at the first document, count goes up and down
with arrows
menu_text.setOrigin(sf::Vector2f(-20.f, 0.f));
menu_text.setFont(font);
while (menu_window.isOpen()) {
// DRAWING
menu_window.clear(backgroundColor); // Setting menu background color
//window.draw(background_overlay);
DrawAllOptions(menu_window, menu_text_options);
// DISPLAYING
menu_window.display();
// TO DO - ABSTRACT USER INPUT LOGIC
while (menu_window.pollEvent(event)) {
switch (event.type)
{
case sf::Event::Closed:
menu_window.close();
return "Test";
break;
case sf::Event::TextEntered:
if (event.text.unicode < 128) {
}
break;
case sf::Event::KeyReleased:
break;
}
}
}
return "Not correctly working";
}
The exact error I get is:
Exception thrown at 0x00007FFA3E2869E9 (sfml-graphics-d-2.dll) in texteditor.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
At this point, I've attempted putting a try catch block, initializing the vector with new and making everything within the main loop function. I am sensing its something to do with the Text objects that I push into the vector, but I tried initializing them differently as well with no success. Any suggestions would be greatly appreciated!
The answer to the problem, as mentioned by #Botje, is that the function Menu::GetAllTextOptions was getting a copy of font, which ultimately ended up not being loaded and resulting in an access violation.
Pretty much the title I am trying to delete a few faces of a mesh using open mesh, like this:
MyMesh mesh;
char fname[1024];
sprintf(fname, "box_%i.obj", 0);
if (!OpenMesh::IO::read_mesh(mesh, std::string(fname)))
{
std::cerr << "read error\n";
exit(1);
}
MyMesh::FaceIter v_it, v_end(mesh.faces_end());
uint count = 0;
for (v_it=mesh.faces_begin(); v_it!=v_end; ++v_it)
{
mesh.delete_face(*v_it, true);
}
This is segfaulting on the first call to delete_face.
However, writing this mesh (without trying to delete faces):
if (!OpenMesh::IO::write_mesh(mesh, std::string("open_mesh.obj")))
{
std::cerr << "write error\n";
exit(1);
}
Works perfectly fine and blender can open the obj. So the issue very much seems to be with how I am trying to delete the faces.
The docs don;t seem to provide any explanation as to why this is not valid:
https://www.graphics.rwth-aachen.de/media/openmesh_static/Documentations/OpenMesh-Doc-Latest/a02618.html#ae20c4e746b52c34ace6a7b805fbd61ac
I think iterator being invalid after removing an element in it.
for (v_it=mesh.faces_begin(); v_it!=v_end; ++v_it)
{
mesh.delete_face(*v_it, true);
v_it = mesh.faces_begin(); //<- add this to test
}
I'm having problem with parsing yaml files using yaml-cpp, I'm making a application using wxWidgets and I'm trying to read the frame size from a yaml file which looks like,
---
This is the configuration file for the Sample Browser,
feel free to edit this file as needed
...
Window:
SizeW: 1280
SizeH: 720
Media:
Autoplay: false
And this the code that should handle the parsing,
int sizeH, sizeW;
try
{
YAML::Node config = YAML::LoadFile("/home/apoorv/repos/cpp-projects/wxWidgets/SampleBrowser/build/config.yaml");
if (!config["Window"])
{
wxLogDebug("Error! Cannot fetch values.");
}
sizeH = config["SizeH"].as<int>();
sizeW = config["SizeW"].as<int>();
}
catch(const YAML::ParserException& ex)
{
std::cout << ex.what() << std::endl;
}
this->SetSize(sizeW, sizeH);
But when I try to parse this file and set the frame size this->SetSize() it errors out saying *** Caught unhandled unknown exception; terminating.
Since SizeH and SizeW are children of Window, your two lines should look like
sizeH = config["Window"]["SizeH"].as<int>();
sizeW = config["Window"]["SizeW"].as<int>();
or, merged with the previous check,
if (auto window = config["Window"]) {
sizeH = window["SizeH"].as<int>();
sizeW = window["SizeW"].as<int>();
} else {
wxLogDebug("Error! Cannot fetch values.");
}
Generally, the error handling is bad. In your code, if an error is encountered, sizeH and sizeW are not set but are still given to SetSize. This is undefined behavior. You should initialize them with some default values, e.g.
int sizeH = 480, sizeW = 640;
Also, since you keep us in the dark about what this is, there may be other errors.
It's fine to try to do this for learning yaml-cpp, but if you really want to save/restore your frame geometry, you should use wxPersistentTLW instead. To use it, just call wxPersistentRegisterAndRestore(frame, "NameToIdentifyYourFrame") after creating your frame, see the manual for more details.
In the cross-platform environment it is better to save the client size of the window, as for GTK what's important is the client size. There might be other OSes/toolkits where this is the case.
I am new to C++ gui design and I am not too familiar with using pointers. Recently I have run into a few problems when trying to get an OpenCV Mat Image to display in a PictureBox in a constructed gui. I have searching online and even found a very similar post to my question but when trying to implement the guidance I ran into an exception when trying to operate the gui.
A very similar post
Displaying webcam feed in cv::Mat format in a picturebox
Code I grabbed from this post to save you a click:
void DrawCVImage(System::Windows::Forms::Control^ control, cv::Mat& colorImage)
{
System::Drawing::Graphics^ graphics = control->CreateGraphics();
System::IntPtr ptr(colorImage.ptr());
System::Drawing::Bitmap^ b = gcnew System::Drawing::Bitmap(colorImage.cols,colorImage.rows,colorImage.step,System::Drawing::Imaging::PixelFormat::Format24bppRgb,ptr);
System::Drawing::RectangleF rect(0,0,control->Width,control->Height);
graphics->DrawImage(b,rect);
delete graphics;
}
Now I am trying to display a "video" feed (really an array of cv::Mat Objects) but I am having a
"Source Not Available"/System.ArgumentException: 'Parameter is not valid.'
screen come up when I attempt to call the function that houses that playback. I also know specific line of code that throws the issue is the line
System::Drawing::Bitmap^ b = gcnew System::Drawing::Bitmap(colorImage.cols,colorImage.rows,colorImage.step,System::Drawing::Imaging::PixelFormat::Format24bppRgb,ptr);
Now for specifics, the form has an event (currently the click on the picture box, but I want to move to a "play" button in the future) and on this event, the code:
private: System::Void leftEyeImage_Click(System::Object^ sender, System::EventArgs^ e) {
std::cout << "Click Received" << std::endl;
cv::Mat& frame = cv::imread("Desktop/testcapture.png");
std::cout << "Import successful" << std::endl;
drawLeftEye(this, frame);
}
This code does get execute on click and starts the function drawLeftEye. The function is a modified version of the code from the other post and is below:
This is on the ShowResults.cpp file
namespace DevProject {
void ShowResults::drawLeftEye(System::Windows::Forms::Control^ control, cv::Mat& framebmp) {
System::Drawing::Graphics^ graphics = control->CreateGraphics();
std::cout << "Now Here" << std::endl;
System::IntPtr ptr(framebmp.data);
// Issue line
System::Drawing::Bitmap^ b = gcnew System::Drawing::Bitmap(framebmp.cols, framebmp.rows, framebmp.step, System::Drawing::Imaging::PixelFormat::Format32bppRgb, ptr);
std::cout << "Converted successfully" << std::endl;
System::Drawing::RectangleF rect(0, 0, control->Width, control->Height); //No issue
graphics->DrawImage(b, rect);
std::cout << "Now Here before delete" << std::endl;
delete graphics;
//delete b;
}
}
I know based on my cout statements that I do make it into my function and I know my code compiles and runs through the function if I comment out the line:
System::Drawing::Bitmap^ b = gcnew System::Drawing::Bitmap(framebmp.cols, framebmp.rows, framebmp.step, System::Drawing::Imaging::PixelFormat::Format32bppRgb, ptr);
//As well as (but only because b is defined in the line above^
graphics->DrawImage(b, rect);
I am not quite sure how to fix this, my friend mentioned this could be a memory issue but I don't know how I would go about fixing it. It is also very possible I have made a simple mistake in the design of this or where my pointers are going and I am just not competent enough to know the error.
By the way the pointer for "this" that is called in the function is linked to the Windows Autogenerated code (from gui construction) of:
this->leftEyeImage->Anchor = System::Windows::Forms::AnchorStyles::None;
this->leftEyeImage->BorderStyle = System::Windows::Forms::BorderStyle::FixedSingle;
this->leftEyeImage->Location = System::Drawing::Point(11, 836);
this->leftEyeImage->Name = L"leftEyeImage";
this->leftEyeImage->Size = System::Drawing::Size(991, 646);
this->leftEyeImage->TabIndex = 4;
this->leftEyeImage->TabStop = false;
this->leftEyeImage->Click += gcnew System::EventHandler(this, &ShowResults::leftEyeImage_Click);
Any and all advice or tests would be very appreciated as I am both interested in the answer and the reasoning. Thanks in advance!
i try this little bit a of code :
try {
InitializeMagick(*argv);
//create a base image
Image image("400x100",font_color);
//construct a drawing list
std::list<Magick::Drawable> drawList;
//add tracing elements
drawList.push_back(DrawableRectangle(0,0,400,100)); // Draw a rectangle ( the sign)
drawList.push_back(DrawableStrokeColor("black")); // Outline Color
drawList.push_back(DrawableFillColor(font_color)); // Fill color
drawList.push_back(DrawableStrokeWidth(5));
drawList.push_back(DrawablePointSize(50));
drawList.push_back(DrawableFont("#Arial"));
drawList.push_back(DrawableStrokeColor(police_color));
drawList.push_back(DrawableText(10,70,ville));
drawList.push_back(DrawableText(300,70,distance));
image.draw(drawList);
image.write(filedest);
}
catch(exception & error_)
{
cout<<"Caught exception : " << error_.what() << endl;
}
but i get this error when i start the program :
proto.exe:unable to read font `#Arial' # error/annotate.c/RenderFreetype/1126
Just drop the # sign in the font name. It's not needed for the Magick::DrawableFont method.
drawList.push_back(DrawableFont("Arial"));
You can verify the fonts available by running the identify utility.
identify -list font | more