Grafický editor využívající ImageMagick a gtkmm - 3. část
28.2.2019
V tomto prozatím závěrečném článku miniseriálu o knihovně ImageMagick, resp. Magick++ si přidáme ukázku zápisu textu do obrázku a také přidání vlastního popisu/komentáře do souboru s obrázkem.
Přidání popisu do souboru
Pro přidání nebo změnu existujícího popisu/komentáře (přímo do souboru s obrázkem) slouží metoda comment třídy Image, která má parametr (požadovaný text) typu std::string.
Obsah aktuálního komentáře zjistíme pomocí metody attribute s parametrem "comment", která vrátí stávající komentář jako std::string.
V našem ukázkovém projektu si pod oblast s obrázkem přidáme widget typu Gtk::ScrolledWindow a do něj Gtk::TextView, do kterého při načtení obrázku nastavíme (pokud existuje) stávající komentář a při uložení obrázku pak použijeme jako komentář text aktuálně nastavení v TextView.
Metodu nacist_soubor si rozšíříme o nastavení aktuálního komentáře do TextView.
void OknoHlavni::nacist_soubor(const char* soubor) noexcept
{
try
{
_obrazek.nacist(soubor);
_nacteny_soubor = soubor;
_oblast_obrazku.set_pixbuf(_obrazek.get_pixbuf());
_tv_popis.get_buffer()->set_text(_obrazek.get_image()->attribute("comment"));
}
catch (std::exception& ex)
{
zprava_chyba(ex.what());
}
}
Při ukládání souboru pak upravíme obsluhu signálu on_soubor_ulozit a on_soubor_ulozit_jako:
void OknoHlavni::on_soubor_ulozit() noexcept
{
_obrazek.get_image()->comment(_tv_popis.get_buffer()->get_text());
_obrazek.get_image()->write(_nacteny_soubor.c_str());
}
void OknoHlavni::on_soubor_ulozit_jako() noexcept
{
if (!_obrazek.je_nacten())
return;
Gtk::FileChooserDialog dialog("Uložit obrázek",
Gtk::FILE_CHOOSER_ACTION_SAVE);
dialog.set_transient_for(*this);
dialog.add_button("_Zrušit", Gtk::RESPONSE_CANCEL);
dialog.add_button("Uložit", Gtk::RESPONSE_OK);
auto filtr = Gtk::FileFilter::create();
filtr->set_name("Obrázky");
filtr->add_mime_type("image/jpeg");
filtr->add_mime_type("image/tiff");
filtr->add_mime_type("image/gif");
dialog.add_filter(filtr);
int result = dialog.run();
if (Gtk::RESPONSE_OK != result)
return;
std::string str_soubor = dialog.get_filename();
_obrazek.get_image()->comment(_tv_popis.get_buffer()->get_text());
_obrazek.get_image()->write(str_soubor.c_str());
}
Zápis textu do obrázku
Pro zápis textu do obrázku slouží metoda annotate, která má více variant ve kterých můžeme kromě vlastního textu nastavit jeho umístění v obrázku. Podrobnější popis samozřejmě lze nalézt v dokumentaci. My zde použijeme variantu která má jako 2. parametr (tím prvním je vždy požadovaný text) jednu z hodnot typu Magick::GravityType, kterou určíme některou stranu či roh obrázku, konkrétně například Magick::SouthEastGravity, která určuje (jak název napovídá těm kteří znají orientaci map podle světových stran :-)) pravý dolní roh.
Pro určení některých parametrů textu máme k disposici další členské funkce třídy Image. My zde použijeme metodu fillColor pro nastavení barvy písma a fontPointSize pro velikost písma.
Do projektu jsem přidal další položku menu a její obsluhu, která vypadá takto:
void OknoHlavni::on_zapsat_text() noexcept
{
std::string str = "Nějaký testovací text";
_obrazek.get_image()->fillColor("#d00000");
_obrazek.get_image()->fontPointsize(50.0);
_obrazek.get_image()->annotate(str, Magick::SouthEastGravity);
_obrazek.aktualizovat_data();
_oblast_obrazku.set_pixbuf(_obrazek.get_pixbuf());
}
Projekt (v CodeLite) si můžete stáhnout v příloze níže.