* scribo/fun/v2v/highlight.hh,
* scribo/io/img/internal/debug_img_visitor.hh,
* scribo/io/img/internal/draw_edges.hh,
* scribo/io/img/internal/full_img_visitor.hh,
* scribo/io/img/internal/non_text_img_visitor.hh,
* scribo/io/img/internal/text_img_visitor.hh,
* scribo/io/img/save.hh: New.
---
scribo/ChangeLog | 12 +
.../serializable.hh => fun/v2v/highlight.hh} | 57 +++--
scribo/scribo/io/img/internal/debug_img_visitor.hh | 263 ++++++++++++++++++++
.../internal/draw_edges.hh} | 62 +++---
scribo/scribo/io/img/internal/full_img_visitor.hh | 194 ++++++++++++++
.../scribo/io/img/internal/non_text_img_visitor.hh | 162 ++++++++++++
scribo/scribo/io/img/internal/text_img_visitor.hh | 164 ++++++++++++
scribo/scribo/io/img/save.hh | 242 ++++++++++++++++++
8 files changed, 1104 insertions(+), 52 deletions(-)
copy scribo/scribo/{core/concept/serializable.hh => fun/v2v/highlight.hh} (66%)
create mode 100644 scribo/scribo/io/img/internal/debug_img_visitor.hh
copy scribo/scribo/io/{xml/internal/print_box_coords.hh => img/internal/draw_edges.hh}
(56%)
create mode 100644 scribo/scribo/io/img/internal/full_img_visitor.hh
create mode 100644 scribo/scribo/io/img/internal/non_text_img_visitor.hh
create mode 100644 scribo/scribo/io/img/internal/text_img_visitor.hh
create mode 100644 scribo/scribo/io/img/save.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 5b96508..43041fe 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,17 @@
2011-03-14 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Introduce result image output.
+
+ * scribo/fun/v2v/highlight.hh,
+ * scribo/io/img/internal/debug_img_visitor.hh,
+ * scribo/io/img/internal/draw_edges.hh,
+ * scribo/io/img/internal/full_img_visitor.hh,
+ * scribo/io/img/internal/non_text_img_visitor.hh,
+ * scribo/io/img/internal/text_img_visitor.hh,
+ * scribo/io/img/save.hh: New.
+
+2011-03-14 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Save image edge coordinates in XML output.
* scribo/io/xml/internal/extended_page_xml_visitor.hh: Here.
diff --git a/scribo/scribo/core/concept/serializable.hh
b/scribo/scribo/fun/v2v/highlight.hh
similarity index 66%
copy from scribo/scribo/core/concept/serializable.hh
copy to scribo/scribo/fun/v2v/highlight.hh
index 6e661a6..835be59 100644
--- a/scribo/scribo/core/concept/serializable.hh
+++ b/scribo/scribo/fun/v2v/highlight.hh
@@ -23,42 +23,55 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef SCRIBO_CORE_CONCEPT_SERIALIZABLE_HH
-# define SCRIBO_CORE_CONCEPT_SERIALIZABLE_HH
+#ifndef SCRIBO_FUN_V2V_HIGHLIGHT_HH
+# define SCRIBO_FUN_V2V_HIGHLIGHT_HH
-/// \file
-///
-/// Concept for serializer visitors.
+/// \brief Function increasing values to highlight areas.
-# include <mln/core/concept/object.hh>
-# include <scribo/core/concept/serialize_visitor.hh>
+# include <mln/core/concept/function.hh>
namespace scribo
{
- /// \brief Link functor concept.
- template <typename E>
- class Serializable : public mln::Object<E>
+ namespace fun
{
- public:
- template <typename E2>
- void accept(const SerializeVisitor<E2>& visitor) const;
- };
+
+ namespace v2v
+ {
+
+ template <typename R>
+ struct highlight
+ : mln::Function_v2v<highlight<R> >
+ {
+ typedef R result;
+
+ highlight();
+ result operator()(const result& v) const;
+ };
# ifndef MLN_INCLUDE_ONLY
- template <typename E>
- template <typename E2>
- void
- Serializable<E>::accept(const SerializeVisitor<E2>& visitor) const
- {
- exact(visitor).visit(exact(*this));
- }
+
+ template <typename R>
+ highlight<R>::highlight()
+ {
+ }
+
+
+ template <typename R>
+ typename highlight<R>::result
+ highlight<R>::operator()(const result& v) const
+ {
+ return v + v / 2;
+ }
# endif // ! MLN_INCLUDE_ONLY
+ } // end of namespace scribo::fun::v2v
+
+ } // end of namespace scribo::fun
} // end of namespace scribo
-#endif // SCRIBO_CORE_CONCEPT_SERIALIZABLE_HH
+#endif // ! SCRIBO_FUN_V2V_HIGHLIGHT_HH
diff --git a/scribo/scribo/io/img/internal/debug_img_visitor.hh
b/scribo/scribo/io/img/internal/debug_img_visitor.hh
new file mode 100644
index 0000000..f1c689d
--- /dev/null
+++ b/scribo/scribo/io/img/internal/debug_img_visitor.hh
@@ -0,0 +1,263 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_IO_IMG_INTERNAL_DEBUG_IMG_VISITOR_HH
+# define SCRIBO_IO_IMG_INTERNAL_DEBUG_IMG_VISITOR_HH
+
+/// \file
+///
+/// Save document image analysis to a small image.
+
+# include <fstream>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/draw/box.hh>
+# include <mln/subsampling/antialiased.hh>
+# include <mln/morpho/elementary/gradient_external.hh>
+
+# include <scribo/core/internal/doc_serializer.hh>
+# include <scribo/core/document.hh>
+# include <scribo/core/paragraph_set.hh>
+# include <scribo/core/line_info.hh>
+
+# include <scribo/io/img/internal/draw_edges.hh>
+
+namespace scribo
+{
+
+ namespace io
+ {
+
+ namespace img
+ {
+
+ namespace internal
+ {
+
+
+ class debug_img_visitor : public doc_serializer<debug_img_visitor>
+ {
+ public:
+ // Constructor
+ debug_img_visitor(mln::image2d<value::rgb8>& out,
+ unsigned output_ratio);
+
+ // Visit overloads
+ template <typename L>
+ void visit(const document<L>& doc) const;
+
+ void visit(const component_info& info) const;
+
+ template <typename L>
+ void visit(const paragraph_set<L>& parset) const;
+
+ template <typename L>
+ void visit(const line_info<L>& line) const;
+
+ private: // Attributes
+ mln::image2d<value::rgb8>& output;
+ unsigned output_ratio;
+
+ mutable image2d<scribo::def::lbl_type> elt_edge;
+
+
+ private: // Methods
+ box2d compute_bbox(const box2d& b) const;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ inline
+ box2d
+ debug_img_visitor::compute_bbox(const box2d& b) const
+ {
+ point2d
+ pmin = b.pmin() / output_ratio,
+ pmax = b.pmax() / output_ratio;
+
+ return box2d(pmin, pmax);
+ }
+
+
+ inline
+ debug_img_visitor::debug_img_visitor(mln::image2d<value::rgb8>& out,
+ unsigned output_ratio)
+ : output(out), output_ratio(output_ratio)
+ {
+ mln_assertion(output.is_valid());
+ }
+
+
+ /// Document
+ //
+ template <typename L>
+ void
+ debug_img_visitor::visit(const document<L>& doc) const
+ {
+ // Text
+ if (doc.has_text())
+ doc.paragraphs().accept(*this);
+
+ // Page elements (Pictures, ...)
+ if (doc.has_elements())
+ {
+ // Prepare element edges
+
+ // FIXME: UGLY! Too slow!
+ scribo::def::lbl_type nlabels;
+ component_set<L> elts = primitive::extract::components(
+ data::convert(bool(),
mln::subsampling::antialiased(doc.elements().labeled_image(),
+ output_ratio)),
+ c8(),
+ nlabels);
+
+ // Preserving elements tags
+ if (doc.elements().nelements() != elts.nelements())
+ {
+ std::cerr << "Warnig: could not preserve element type in "
+ << "img debug output." << std::endl;
+ std::cerr << "The number of non text element has changed while "
+ << "subsampling images : "
+ << doc.elements().nelements() << " vs "
+ << elts.nelements() << std::endl;
+ }
+ else
+ for_all_comps(c, doc.elements())
+ elts(c).update_type(doc.elements()(c).type());
+
+ elt_edge = morpho::elementary::gradient_external(elts.labeled_image(), c8());
+
+// const component_set<L>& elts = doc.elements();
+ for_all_comps(e, elts)
+ if (elts(e).is_valid())
+ elts(e).accept(*this);
+ }
+
+
+ // line seraparators
+ if (doc.has_vline_seps())
+ for_all_comps(c, doc.vline_seps_comps())
+ doc.vline_seps_comps()(c).accept(*this);
+ if (doc.has_hline_seps())
+ for_all_comps(c, doc.hline_seps_comps())
+ doc.hline_seps_comps()(c).accept(*this);
+
+ }
+
+
+ /// Component_info
+ //
+ inline
+ void
+ debug_img_visitor::visit(const component_info& info) const
+ {
+ switch (info.type())
+ {
+ case component::LineSeparator:
+ {
+ mln::draw::box(output, compute_bbox(info.bbox()),
+ literal::cyan);
+ }
+ break;
+
+
+ default:
+ case component::Image:
+ {
+ // The bbox does not need to be reajusted to the
+ // subsampled domain since it has been recomputed while
+ // computing the edge image.
+ //
+ // However, the bbox must be enlarged since only the
+ // _external_ edge is computed.
+ box2d b = info.bbox();
+ b.enlarge(1);
+ b.crop_wrt(output.domain());
+ data::fill(((output | b).rw()
+ | (pw::value(elt_edge)
+ == pw::cst((scribo::def::lbl_type)info.id().to_equiv()))).rw(),
+ literal::orange);
+ }
+ break;
+ }
+ }
+
+ /// Paragraph Set
+ //
+ template <typename L>
+ void
+ debug_img_visitor::visit(const paragraph_set<L>& parset) const
+ {
+ const line_set<L>& lines = parset.lines();
+
+ for_all_paragraphs(p, parset)
+ {
+ const mln::util::array<line_id_t>& line_ids = parset(p).line_ids();
+
+ for_all_paragraph_lines(lid, line_ids)
+ {
+ line_id_t l = line_ids(lid);
+ lines(l).accept(*this);
+ }
+
+ box2d b = compute_bbox(parset(p).bbox());
+ b.enlarge(1);
+ b.crop_wrt(output.domain());
+ mln::draw::box(output, b, literal::blue);
+ }
+ }
+
+
+ template <typename L>
+ void
+ debug_img_visitor::visit(const line_info<L>& line) const
+ {
+ point2d
+ pmin = line.bbox().pmin(),
+ pmax = line.bbox().pmax();
+ pmax.row() = line.baseline();
+ pmin.row() = line.baseline();
+
+ pmin = pmin / output_ratio;
+ pmax = pmax / output_ratio;
+
+ mln::draw::line(output, pmin, pmax, literal::red);
+ }
+
+#endif // MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::io::img::internal
+
+ } // end of namespace scribo::io::img
+
+ } // end of namespace scribo::io
+
+} // end of namespace scribo
+
+#endif // SCRIBO_IO_IMG_INTERNAL_DEBUG_IMG_VISITOR_HH
diff --git a/scribo/scribo/io/xml/internal/print_box_coords.hh
b/scribo/scribo/io/img/internal/draw_edges.hh
similarity index 56%
copy from scribo/scribo/io/xml/internal/print_box_coords.hh
copy to scribo/scribo/io/img/internal/draw_edges.hh
index ad84709..664a352 100644
--- a/scribo/scribo/io/xml/internal/print_box_coords.hh
+++ b/scribo/scribo/io/img/internal/draw_edges.hh
@@ -23,15 +23,26 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef SCRIBO_IO_XML_INTERNAL_PRINT_BOX_COORDS_HH
-# define SCRIBO_IO_XML_INTERNAL_PRINT_BOX_COORDS_HH
+#ifndef SCRIBO_IO_IMG_INTERNAL_DRAW_EDGES_HH
+# define SCRIBO_IO_IMG_INTERNAL_DRAW_EDGES_HH
/// \file
///
-/// \brief Prints box2d coordinates to XML data.
+/// \brief Draw object edges.
# include <fstream>
-# include <mln/core/alias/box2d.hh>
+# include <mln/core/image/image2d.hh>
+# include <mln/core/image/dmorph/image_if.hh>
+# include <mln/pw/all.hh>
+# include <mln/data/fill.hh>
+# include <mln/data/convert.hh>
+# include <mln/literal/colors.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/morpho/elementary/gradient_external.hh>
+
+# include <scribo/core/component_info.hh>
+# include <scribo/core/def/lbl_type.hh>
+
namespace scribo
{
@@ -39,7 +50,7 @@ namespace scribo
namespace io
{
- namespace xml
+ namespace img
{
namespace internal
@@ -47,11 +58,12 @@ namespace scribo
using namespace mln;
- /*! \brief Prints box2d coordinates to XML data.
+ /*! \brief Draw component edges.
*/
void
- print_box_coords(std::ofstream& ostr, const box2d& b,
- const char *space);
+ draw_edges(const component_info& info,
+ image2d<value::rgb8>& output, const value::rgb8& value,
+ const image2d<scribo::def::lbl_type>& edges);
# ifndef MLN_INCLUDE_ONLY
@@ -59,37 +71,27 @@ namespace scribo
inline
void
- print_box_coords(std::ofstream& ostr, const box2d& b,
- const char *space)
+ draw_edges(const component_info& info,
+ image2d<value::rgb8>& output, const value::rgb8& value,
+ const image2d<scribo::def::lbl_type>& edges)
{
- std::string sc = space;
- std::string sp = sc + " ";
- ostr << sc << "<coords>" << std::endl
- << sp << "<point x=\"" << b.pmin().col()
- << "\" y=\"" << b.pmin().row() <<
"\"/>"
- << std::endl
- << sp << "<point x=\"" << b.pmax().col()
- << "\" y=\"" << b.pmin().row() <<
"\"/>"
- << std::endl
- << sp << "<point x=\"" << b.pmax().col()
- << "\" y=\"" << b.pmax().row() <<
"\"/>"
- << std::endl
- << sp << "<point x=\"" << b.pmin().col()
- << "\" y=\"" << b.pmax().row() <<
"\"/>"
- << std::endl
- << sc << "</coords>" << std::endl;
-
+ box2d b = info.bbox();
+ b.enlarge(1);
+ data::fill(((output | b).rw()
+ | (pw::value(edges)
+ == pw::cst((scribo::def::lbl_type)info.id().to_equiv()))).rw(),
+ value);
}
# endif // ! MLN_INCLUDE_ONLY
- } // end of namespace scribo::io::xml::internal
+ } // end of namespace scribo::io::img::internal
- } // end of namespace scribo::io::xml
+ } // end of namespace scribo::io::img
} // end of namespace scribo::io
} // end of namespace scribo
-#endif // ! SCRIBO_IO_XML_INTERNAL_PRINT_BOX_COORDS_HH
+#endif // ! SCRIBO_IO_IMG_INTERNAL_DRAW_EDGES_HH
diff --git a/scribo/scribo/io/img/internal/full_img_visitor.hh
b/scribo/scribo/io/img/internal/full_img_visitor.hh
new file mode 100644
index 0000000..30987db
--- /dev/null
+++ b/scribo/scribo/io/img/internal/full_img_visitor.hh
@@ -0,0 +1,194 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_IO_IMG_INTERNAL_FULL_IMG_VISITOR_HH
+# define SCRIBO_IO_IMG_INTERNAL_FULL_IMG_VISITOR_HH
+
+/// \file
+///
+/// Save document image analysis to an image.
+
+# include <fstream>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/draw/box.hh>
+
+# include <scribo/core/internal/doc_serializer.hh>
+# include <scribo/core/document.hh>
+# include <scribo/core/paragraph_set.hh>
+# include <scribo/core/line_info.hh>
+
+# include <scribo/io/img/internal/draw_edges.hh>
+
+namespace scribo
+{
+
+ namespace io
+ {
+
+ namespace img
+ {
+
+ namespace internal
+ {
+
+
+ class full_img_visitor : public doc_serializer<full_img_visitor>
+ {
+ public:
+ // Constructor
+ full_img_visitor(mln::image2d<value::rgb8>& out);
+
+ // Visit overloads
+ template <typename L>
+ void visit(const document<L>& doc) const;
+
+ void visit(const component_info& info) const;
+
+ template <typename L>
+ void visit(const paragraph_set<L>& parset) const;
+
+ template <typename L>
+ void visit(const line_info<L>& line) const;
+
+ private: // Attributes
+ mln::image2d<value::rgb8>& output;
+
+ mutable image2d<scribo::def::lbl_type> elt_edge;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ inline
+ full_img_visitor::full_img_visitor(mln::image2d<value::rgb8>& out)
+ : output(out)
+ {
+ mln_assertion(output.is_valid());
+ }
+
+
+ /// Document
+ //
+ template <typename L>
+ void
+ full_img_visitor::visit(const document<L>& doc) const
+ {
+ // Text
+ if (doc.has_text())
+ doc.paragraphs().accept(*this);
+
+ // Page elements (Pictures, ...)
+ if (doc.has_elements())
+ {
+ // Prepare element edges
+ elt_edge = morpho::elementary::gradient_external(doc.elements().labeled_image(),
c8());
+
+ const component_set<L>& elts = doc.elements();
+ for_all_comps(e, elts)
+ if (elts(e).is_valid())
+ elts(e).accept(*this);
+ }
+
+
+ // line seraparators
+ if (doc.has_vline_seps())
+ for_all_comps(c, doc.vline_seps_comps())
+ doc.vline_seps_comps()(c).accept(*this);
+ if (doc.has_hline_seps())
+ for_all_comps(c, doc.hline_seps_comps())
+ doc.hline_seps_comps()(c).accept(*this);
+
+ }
+
+
+ /// Component_info
+ //
+ inline
+ void
+ full_img_visitor::visit(const component_info& info) const
+ {
+ switch (info.type())
+ {
+ case component::LineSeparator:
+ {
+ mln::draw::box(output, info.bbox(), literal::cyan);
+ }
+ break;
+
+
+ default:
+ case component::Image:
+ {
+ draw_edges(info, output, literal::orange, elt_edge);
+ }
+ break;
+ }
+ }
+
+ /// Paragraph Set
+ //
+ template <typename L>
+ void
+ full_img_visitor::visit(const paragraph_set<L>& parset) const
+ {
+ const line_set<L>& lines = parset.lines();
+
+ for_all_paragraphs(p, parset)
+ {
+ const mln::util::array<line_id_t>& line_ids = parset(p).line_ids();
+
+ for_all_paragraph_lines(lid, line_ids)
+ {
+ line_id_t l = line_ids(lid);
+ lines(l).accept(*this);
+ }
+
+ mln::draw::box(output, parset(p).bbox(), literal::blue);
+ }
+ }
+
+
+ template <typename L>
+ void
+ full_img_visitor::visit(const line_info<L>& line) const
+ {
+ mln::draw::box(output, line.bbox(), literal::red);
+ }
+
+#endif // MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::io::img::internal
+
+ } // end of namespace scribo::io::img
+
+ } // end of namespace scribo::io
+
+} // end of namespace scribo
+
+#endif // SCRIBO_IO_IMG_INTERNAL_FULL_IMG_VISITOR_HH
diff --git a/scribo/scribo/io/img/internal/non_text_img_visitor.hh
b/scribo/scribo/io/img/internal/non_text_img_visitor.hh
new file mode 100644
index 0000000..24b027e
--- /dev/null
+++ b/scribo/scribo/io/img/internal/non_text_img_visitor.hh
@@ -0,0 +1,162 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_IO_IMG_INTERNAL_NON_TEXT_IMG_VISITOR_HH
+# define SCRIBO_IO_IMG_INTERNAL_NON_TEXT_IMG_VISITOR_HH
+
+/// \file
+///
+/// \brief Save non-text information as an image.
+
+# include <fstream>
+
+
+# include <mln/core/image/image2d.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/draw/box.hh>
+
+# include <scribo/core/internal/doc_serializer.hh>
+# include <scribo/io/img/internal/draw_edges.hh>
+
+namespace scribo
+{
+
+ namespace io
+ {
+
+ namespace img
+ {
+
+ namespace internal
+ {
+
+ /*! \brief Save non-text information as an image.
+ */
+ class non_text_img_visitor : public doc_serializer<non_text_img_visitor>
+ {
+ public:
+ // Constructor
+ non_text_img_visitor(mln::image2d<value::rgb8>& out);
+
+ // Visit overloads
+ template <typename L>
+ void visit(const document<L>& doc) const;
+
+ template <typename L>
+ void visit(const component_set<L>& comp_set) const;
+
+ void visit(const component_info& info) const;
+
+ private: // Attributes
+ mln::image2d<value::rgb8>& output;
+
+ mutable image2d<scribo::def::lbl_type> elt_edge;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ inline
+ non_text_img_visitor::non_text_img_visitor(mln::image2d<value::rgb8>& out)
+ : output(out)
+ {
+ mln_assertion(output.is_valid());
+ }
+
+
+
+ /// Document
+ //
+ template <typename L>
+ void
+ non_text_img_visitor::visit(const document<L>& doc) const
+ {
+ // Page elements (Pictures, ...)
+ if (doc.has_elements())
+ {
+ // Prepare element edges
+ elt_edge = morpho::elementary::gradient_external(doc.elements().labeled_image(),
c8());
+
+ doc.elements().accept(*this);
+ }
+
+ // line seraparators
+ if (doc.has_hline_seps())
+ doc.hline_seps_comps().accept(*this);
+ if (doc.has_vline_seps())
+ doc.vline_seps_comps().accept(*this);
+ }
+
+
+ /// Component Set
+ //
+ template <typename L>
+ void
+ non_text_img_visitor::visit(const component_set<L>& comp_set) const
+ {
+ for_all_comps(c, comp_set)
+ if (comp_set(c).is_valid())
+ comp_set(c).accept(*this);
+ }
+
+
+ /// Component_info
+ //
+ inline
+ void
+ non_text_img_visitor::visit(const component_info& info) const
+ {
+ switch (info.type())
+ {
+ case component::LineSeparator:
+ {
+ mln::draw::box(output, info.bbox(), literal::cyan);
+ }
+ break;
+
+
+ default:
+ case component::Image:
+ {
+ draw_edges(info, output, literal::orange, elt_edge);
+ }
+ break;
+ }
+ }
+
+
+#endif // MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::io::img::internal
+
+ } // end of namespace scribo::io::img
+
+ } // end of namespace scribo::io
+
+} // end of namespace scribo
+
+#endif // SCRIBO_IO_IMG_INTERNAL_NON_TEXT_IMG_VISITOR_HH
diff --git a/scribo/scribo/io/img/internal/text_img_visitor.hh
b/scribo/scribo/io/img/internal/text_img_visitor.hh
new file mode 100644
index 0000000..7629bf7
--- /dev/null
+++ b/scribo/scribo/io/img/internal/text_img_visitor.hh
@@ -0,0 +1,164 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_IO_IMG_INTERNAL_TEXT_IMG_VISITOR_HH
+# define SCRIBO_IO_IMG_INTERNAL_TEXT_IMG_VISITOR_HH
+
+/// \file
+///
+/// Image output with text related information.
+
+# include <fstream>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/draw/box.hh>
+# include <mln/literal/colors.hh>
+
+# include <scribo/core/internal/doc_serializer.hh>
+# include <scribo/core/document.hh>
+# include <scribo/core/component_set.hh>
+# include <scribo/core/paragraph_set.hh>
+# include <scribo/core/line_info.hh>
+
+namespace scribo
+{
+
+ namespace io
+ {
+
+ namespace img
+ {
+
+ namespace internal
+ {
+
+
+ class text_img_visitor : public doc_serializer<text_img_visitor>
+ {
+ public:
+ // Constructor
+ text_img_visitor(mln::image2d<value::rgb8>&);
+
+ // Visit overloads
+ template <typename L>
+ void visit(const document<L>& doc) const;
+
+ template <typename L>
+ void visit(const component_set<L>& comp_set) const;
+
+ template <typename L>
+ void visit(const paragraph_set<L>& parset) const;
+
+ template <typename L>
+ void visit(const line_info<L>& line) const;
+
+ private: // Attributes
+ mln::image2d<value::rgb8>& output;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ inline
+ text_img_visitor::text_img_visitor(mln::image2d<value::rgb8>& out)
+ : output(out)
+ {
+ mln_assertion(output.is_valid());
+ }
+
+
+
+ /// Document
+ //
+ template <typename L>
+ void
+ text_img_visitor::visit(const document<L>& doc) const
+ {
+ mln_precondition(doc.is_open());
+
+ // Prepare output image.
+ output = duplicate(doc.image());
+
+
+ // Text
+ if (doc.has_text())
+ doc.paragraphs().accept(*this);
+ }
+
+ /// Component Set
+ //
+ template <typename L>
+ void
+ text_img_visitor::visit(const component_set<L>& comp_set) const
+ {
+ for_all_comps(c, comp_set)
+ if (comp_set(c).is_valid())
+ comp_set(c).accept(*this);
+ }
+
+
+ /// Paragraph Set
+ //
+ template <typename L>
+ void
+ text_img_visitor::visit(const paragraph_set<L>& parset) const
+ {
+ const line_set<L>& lines = parset.lines();
+
+ for_all_paragraphs(p, parset)
+ {
+ const mln::util::array<line_id_t>& line_ids = parset(p).line_ids();
+
+ for_all_paragraph_lines(lid, line_ids)
+ {
+ line_id_t l = line_ids(lid);
+ lines(l).accept(*this);
+ }
+
+ mln::draw::box(output, parset(p).bbox(), literal::blue);
+ }
+ }
+
+
+ template <typename L>
+ void
+ text_img_visitor::visit(const line_info<L>& line) const
+ {
+ mln::draw::box(output, line.bbox(), literal::red);
+ }
+
+#endif // MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::io::img::internal
+
+ } // end of namespace scribo::io::img
+
+ } // end of namespace scribo::io
+
+} // end of namespace scribo
+
+#endif // SCRIBO_IO_IMG_INTERNAL_TEXT_IMG_VISITOR_HH
diff --git a/scribo/scribo/io/img/save.hh b/scribo/scribo/io/img/save.hh
new file mode 100644
index 0000000..56300d6
--- /dev/null
+++ b/scribo/scribo/io/img/save.hh
@@ -0,0 +1,242 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_IO_IMG_SAVE_HH
+# define SCRIBO_IO_IMG_SAVE_HH
+
+/// \file
+///
+/// \brief Save document information as an image.
+
+# include <libgen.h>
+# include <fstream>
+# include <sstream>
+
+# include <map>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/io/magick/save.hh>
+# include <mln/subsampling/antialiased.hh>
+# include <mln/data/transform_inplace.hh>
+
+# include <scribo/core/document.hh>
+
+# include <scribo/io/img/internal/text_img_visitor.hh>
+# include <scribo/io/img/internal/non_text_img_visitor.hh>
+# include <scribo/io/img/internal/full_img_visitor.hh>
+# include <scribo/io/img/internal/debug_img_visitor.hh>
+
+
+namespace scribo
+{
+
+ namespace io
+ {
+
+ namespace img
+ {
+
+ /*! \brief Supported image formats
+
+ Text : Display text regions.
+
+ NonText : Display non-text regions.
+
+ Full : Text and non-text regions.
+ */
+ enum Format
+ {
+ Text,
+ NonText,
+ Full,
+ DebugWoImage,
+ DebugWithImage,
+ };
+
+
+ /*! \brief Save document information as an image
+
+ */
+ template <typename L>
+ void
+ save(const document<L>& doc, const std::string& output_name,
+ Format format);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace internal
+ {
+
+ struct highlight_mask
+ : Function_v2v<highlight_mask>
+ {
+ typedef value::rgb8 result;
+
+ highlight_mask(float ratio)
+ : ratio(ratio)
+ {
+ }
+
+ result operator()(const result& v) const
+ {
+ result out = v;
+ out.red() = std::min(out.red() * ratio, 255.f);
+ out.green() = std::min(out.green() * ratio, 255.f);
+ out.blue() = std::min(out.blue() * ratio, 255.f);
+ return out;
+ }
+
+ float ratio;
+ };
+
+
+ template <typename L>
+ mln::image2d<value::rgb8>
+ save_text(const document<L>& doc)
+ {
+ mln_precondition(doc.is_valid());
+ mln::image2d<value::rgb8> output = duplicate(doc.image());
+ scribo::io::img::internal::text_img_visitor f(output);
+ doc.accept(f);
+ return output;
+ }
+
+ template <typename L>
+ mln::image2d<value::rgb8>
+ save_non_text(const document<L>& doc)
+ {
+ mln_precondition(doc.is_valid());
+ mln::image2d<value::rgb8> output = duplicate(doc.image());
+ scribo::io::img::internal::non_text_img_visitor f(output);
+ doc.accept(f);
+ return output;
+ }
+
+ template <typename L>
+ mln::image2d<value::rgb8>
+ save_full(const document<L>& doc)
+ {
+ mln_precondition(doc.is_valid());
+ mln::image2d<value::rgb8> output = duplicate(doc.image());
+ scribo::io::img::internal::full_img_visitor f(output);
+ doc.accept(f);
+ return output;
+ }
+
+ template <typename L>
+ mln::image2d<value::rgb8>
+ save_debug_without_image(const document<L>& doc)
+ {
+ mln_precondition(doc.is_valid());
+ mln::image2d<value::rgb8>
+ output(box2d(doc.image().domain().pmin() / 4,
+ doc.image().domain().pmax() / 4));
+ data::fill(output, literal::black);
+ scribo::io::img::internal::debug_img_visitor f(output, 4);
+ doc.accept(f);
+ return output;
+ }
+
+ template <typename L>
+ mln::image2d<value::rgb8>
+ save_debug_with_image(const document<L>& doc)
+ {
+ mln_precondition(doc.is_valid());
+ mln::image2d<value::rgb8>
+ output = mln::subsampling::antialiased(doc.image(), 4);
+ internal::highlight_mask highlight(0.5f);
+ data::transform_inplace(output, highlight);
+ scribo::io::img::internal::debug_img_visitor f(output, 4);
+ doc.accept(f);
+ return output;
+ }
+
+ } // end of namespace scribo::io::img::internal
+
+
+
+ // FACADE
+
+ template <typename L>
+ void
+ save(const document<L>& doc,
+ const std::string& output_name,
+ Format format)
+ {
+ trace::entering("scribo::io::img::save");
+
+ mln_precondition(doc.is_open());
+
+ mln::image2d<value::rgb8> output;
+
+ // Choose saving method.
+ switch (format)
+ {
+ case Text:
+ output = internal::save_text(doc);
+ break;
+
+ case NonText:
+ output = internal::save_non_text(doc);
+ break;
+
+ case Full:
+ output = internal::save_full(doc);
+ break;
+
+ case DebugWoImage:
+ output = internal::save_debug_without_image(doc);
+ break;
+
+ case DebugWithImage:
+ output = internal::save_debug_with_image(doc);
+ break;
+
+ default:
+ trace::warning("scribo::io::img::save - "
+ "Invalid image format! Skip saving...");
+ trace::exiting("scribo::io::img::save");
+ return;
+ }
+
+ mln::io::magick::save(output, output_name.c_str());
+
+ trace::exiting("scribo::io::img::save");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::io::img
+
+ } // end of namespace scribo::io
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_IO_IMG_SAVE_HH
--
1.5.6.5