//---------------------------------------------------------------------------
/*
TestAsciiArter, tool to test the AsciiArter class
Copyright (C) 2006-2011 Richel Bilderbeek
This program 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, either version 3 of the License, or
(at your option) any later version.
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/ToolTestAsciiArter.htm
//---------------------------------------------------------------------------
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/numeric/conversion/cast.hpp>
//---------------------------------------------------------------------------
#include <Wt/WBreak>
#include <Wt/WFileUpload>
#include <Wt/WImage>
#include <Wt/WLabel>
#include <Wt/WLineEdit>
#include <Wt/WMenu>
#include <Wt/WPushButton>
#include <Wt/WStackedWidget>
#include <Wt/WTextArea>
//---------------------------------------------------------------------------
#include <QtGui/QImage>
//---------------------------------------------------------------------------
#include "about.h"
#include "asciiarter.h"
#include "testasciiarterdialog.h"
#include "wtaboutdialog.h"
#include "wtautoconfig.h"
#include "wttestasciiarterdialog.h"
//---------------------------------------------------------------------------
//Enable debugging
#undef NDEBUG
#include <cassert>
//---------------------------------------------------------------------------
WtTestAsciiArterDialog::WtTestAsciiArterDialog()
: m_dialog(new TestAsciiArterDialog),
m_edit_width(0),
m_text(0)
{
this->setContentAlignment(Wt::AlignCenter);
m_dialog->SetWidth(79);
this->clear();
//Title
{
Wt::WLabel * const title = new Wt::WLabel("TestAsciiArter");
title->setStyleClass("title");
this->addWidget(title);
}
this->addWidget(new Wt::WBreak);
//Menu
{
Wt::WStackedWidget * const contents = new Wt::WStackedWidget;
Wt::WMenu * const menu = new Wt::WMenu(contents,Wt::Horizontal);
//Using CSS styleclass is the best (only?) way to display the menu well
menu->setStyleClass("menu");
{
Wt::WMenuItem * const item = new Wt::WMenuItem(
"Welcome",
CreateNewWelcomeDialog());
menu->addItem(item);
}
{
Wt::WMenuItem * const item = new Wt::WMenuItem(
"Start",
CreateNewMainDialog());
menu->addItem(item);
}
{
Wt::WMenuItem * const item = new Wt::WMenuItem(
"About",
CreateNewAboutDialog());
menu->addItem(item);
}
//Display menu on top
this->addWidget(menu);
this->addWidget(new Wt::WBreak);
//Display contents below menu
this->addWidget(contents);
}
this->addWidget(new Wt::WBreak);
assert(m_edit_width);
assert(m_text);
}
//---------------------------------------------------------------------------
Wt::WWidget * WtTestAsciiArterDialog::CreateNewAboutDialog() const
{
About a = TestAsciiArterDialog::GetAbout();
a.AddLibrary("WtAutoConfig version: " + WtAutoConfig::GetVersion());
WtAboutDialog * const d = new WtAboutDialog(a);
return d;
}
//---------------------------------------------------------------------------
Wt::WWidget * WtTestAsciiArterDialog::CreateNewMainDialog()
{
Wt::WContainerWidget * dialog = new Wt::WContainerWidget;
//File upload
{
m_fileupload = new Wt::WFileUpload;
//Upload automatically when the user entered a file
m_fileupload->changed().connect(
m_fileupload,
&Wt::WFileUpload::upload);
//Call WtTextUploadDialog::on_upload_done when file is uploaded
m_fileupload->uploaded().connect(
this,
&WtTestAsciiArterDialog::OnUploadDone);
dialog->addWidget(m_fileupload);
}
dialog->addWidget(new Wt::WBreak);
dialog->addWidget(new Wt::WBreak);
//Width edit
{
m_edit_width = new Wt::WLineEdit(
boost::lexical_cast<std::string>(m_dialog->GetWidth()));
//Respond to if user presses enter
m_edit_width->enterPressed().connect(
this, &WtTestAsciiArterDialog::OnEditWidthChange);
dialog->addWidget(m_edit_width);
}
//Convert button
{
Wt::WPushButton * const button = new Wt::WPushButton("Convert");
button->clicked().connect(
this, &WtTestAsciiArterDialog::OnConvertClick);
dialog->addWidget(button);
}
dialog->addWidget(new Wt::WBreak);
dialog->addWidget(new Wt::WBreak);
//text
{
m_text = new Wt::WTextArea;
m_text->setMinimumSize(600,600);
dialog->addWidget(m_text);
}
//OnAnyChange();
return dialog;
}
//---------------------------------------------------------------------------
Wt::WWidget * WtTestAsciiArterDialog::CreateNewWelcomeDialog() const
{
Wt::WContainerWidget * dialog = new Wt::WContainerWidget;
dialog->setContentAlignment(Wt::AlignCenter);
dialog->addWidget(new Wt::WBreak);
new Wt::WLabel("Welcome to AsciiArter!",dialog);
new Wt::WBreak(dialog);
new Wt::WBreak(dialog);
new Wt::WLabel("AsciiArter is a tool to convert images to ascii art.",dialog);
return dialog;
}
//---------------------------------------------------------------------------
void WtTestAsciiArterDialog::OnAnyChange()
{
if (m_dialog->CanConvert())
{
m_dialog->Convert();
std::vector<std::string> v = m_dialog->GetAsciiArt();
Wt::WString ws;
BOOST_FOREACH(const std::string& s,v)
{
ws += s.c_str();
ws += "\n";
}
m_text->setText(ws);
}
}
//---------------------------------------------------------------------------
void WtTestAsciiArterDialog::OnConvertClick()
{
OnEditWidthChange();
}
//---------------------------------------------------------------------------
void WtTestAsciiArterDialog::OnEditWidthChange()
{
try
{
const std::string s = m_edit_width->text().toUTF8();
const int i = boost::lexical_cast<int>(s);
m_dialog->SetWidth(i);
}
catch(boost::bad_lexical_cast&)
{
//No problem
}
OnAnyChange();
}
//---------------------------------------------------------------------------
void WtTestAsciiArterDialog::OnUploadDone()
{
const std::string filename = m_fileupload->spoolFileName();
assert(boost::filesystem::exists(filename));
const std::vector<std::vector<double> > v
= ConvertToGreyYx(filename);
assert(!v.empty());
m_dialog->SetImage(v);
OnAnyChange();
}
//---------------------------------------------------------------------------
//Returns a Y-X-ordered std::vector of greynesses.
const std::vector<std::vector<double> >
WtTestAsciiArterDialog::ConvertToGreyYx(const std::string& filename)
{
assert(boost::filesystem::exists(filename));
const QImage * const i = new QImage(filename.c_str());
const int maxy = i->height();
const int maxx = i->width();
const int n_bytes = i->bytesPerLine() / maxx;
std::vector<std::vector<double> > v;
for (int y=0; y!=maxy; ++y)
{
v.push_back(std::vector<double>());
const unsigned char * const line = i->scanLine(y);
for (int x=0; x!=maxx; ++x)
{
int sum = 0;
for (int byte=0; byte!=n_bytes; ++byte)
{
sum += line[(x * n_bytes) + byte];
}
const double greyness
= (boost::numeric_cast<double>(sum)
/ boost::numeric_cast<double>(n_bytes))
/ 256.0;
assert(greyness >= 0.0);
assert(greyness <= 1.0);
v.back().push_back(greyness);
}
}
return v;
}
//---------------------------------------------------------------------------
|