adding more zoom levels to the image editor

This commit is contained in:
Alberto Griggio 2017-03-16 14:33:26 +01:00
parent 3660ed5f95
commit feed87d046
3 changed files with 82 additions and 65 deletions

View File

@ -30,7 +30,7 @@
using namespace rtengine; using namespace rtengine;
CropHandler::CropHandler () CropHandler::CropHandler ()
: zoom(10), ww(0), wh(0), imx(-1), imy(-1), imw(0), imh(0), cax(-1), cay(-1), : zoom(100), ww(0), wh(0), imx(-1), imy(-1), imw(0), imh(0), cax(-1), cay(-1),
cx(0), cy(0), cw(0), ch(0), cropX(0), cropY(0), cropW(0), cropH(0), enabled(false), cx(0), cy(0), cw(0), ch(0), cropX(0), cropY(0), cropW(0), cropH(0), enabled(false),
cropimg(nullptr), cropimgtrue(nullptr), cropimg_width(0), cropimg_height(0), cropimg(nullptr), cropimgtrue(nullptr), cropimg_width(0), cropimg_height(0),
cix(0), ciy(0), ciw(0), cih(0), cis(1), cix(0), ciy(0), ciw(0), cih(0), cis(1),
@ -145,8 +145,8 @@ void CropHandler::setZoom (int z, int centerx, int centery)
assert (ipc); assert (ipc);
int oldZoom = zoom; int oldZoom = zoom;
float oldScale = zoom >= 1000 ? float(zoom / 1000) : 1.f / float(zoom); float oldScale = zoom >= 1000 ? float(zoom / 1000) : 10.f / float(zoom);
float newScale = z >= 1000 ? float(z / 1000) : 1.f / float(z); float newScale = z >= 1000 ? float(z / 1000) : 10.f / float(z);
int oldcax = cax; int oldcax = cax;
int oldcay = cay; int oldcay = cay;
@ -176,8 +176,8 @@ void CropHandler::setZoom (int z, int centerx, int centery)
cw = ww * 1000 / zoom; cw = ww * 1000 / zoom;
ch = wh * 1000 / zoom; ch = wh * 1000 / zoom;
} else { } else {
cw = ww * zoom; cw = ww * zoom / 10;
ch = wh * zoom; ch = wh * zoom / 10;
} }
cx = cax - cw / 2; cx = cax - cw / 2;
@ -206,7 +206,7 @@ float CropHandler::getZoomFactor ()
if (zoom >= 1000) { if (zoom >= 1000) {
return zoom / 1000; return zoom / 1000;
} else { } else {
return 1.f / (float)zoom; return 10.f / (float)zoom;
} }
} }
@ -221,8 +221,8 @@ void CropHandler::setWSize (int w, int h)
cw = ww * 1000 / zoom; cw = ww * 1000 / zoom;
ch = wh * 1000 / zoom; ch = wh * 1000 / zoom;
} else { } else {
cw = ww * zoom; cw = ww * zoom/10;
ch = wh * zoom; ch = wh * zoom/10;
} }
compDim (); compDim ();
@ -320,7 +320,7 @@ void CropHandler::setDetailedCrop (IImage8* im, IImage8* imtrue, rtengine::procp
cropimgtrue = nullptr; cropimgtrue = nullptr;
if (ax == cropX && ay == cropY && aw == cropW && ah == cropH && askip == (zoom >= 1000 ? 1 : zoom)) { if (ax == cropX && ay == cropY && aw == cropW && ah == cropH && askip == (zoom >= 1000 ? 1 : zoom/10)) {
cropimg_width = im->getWidth (); cropimg_width = im->getWidth ();
cropimg_height = im->getHeight (); cropimg_height = im->getHeight ();
cropimg = new unsigned char [3 * cropimg_width * cropimg_height]; cropimg = new unsigned char [3 * cropimg_width * cropimg_height];
@ -362,11 +362,14 @@ void CropHandler::setDetailedCrop (IImage8* im, IImage8* imtrue, rtengine::procp
} }
if (ch->cropimg) { if (ch->cropimg) {
if (ch->cix == ch->cropX && ch->ciy == ch->cropY && ch->ciw == ch->cropW && ch->cih == ch->cropH && ch->cis == (ch->zoom >= 1000 ? 1 : ch->zoom)) { if (ch->cix == ch->cropX && ch->ciy == ch->cropY && ch->ciw == ch->cropW && ch->cih == ch->cropH && ch->cis == (ch->zoom >= 1000 ? 1 : ch->zoom/10)) {
// calculate final image size // calculate final image size
int czoom = ch->zoom < 1000 ? 1000 : ch->zoom; //int czoom = ch->zoom < 1000 ? 1000 : ch->zoom;
int imw = ch->cropimg_width * czoom / 1000; float czoom = ch->zoom >= 1000 ?
int imh = ch->cropimg_height * czoom / 1000; ch->zoom / 1000.f :
float((ch->zoom/10) * 10) / float(ch->zoom);
int imw = ch->cropimg_width * czoom;// / 1000;
int imh = ch->cropimg_height * czoom;// / 1000;
if (imw > ch->ww) { if (imw > ch->ww) {
imw = ch->ww; imw = ch->ww;
@ -378,12 +381,12 @@ void CropHandler::setDetailedCrop (IImage8* im, IImage8* imtrue, rtengine::procp
Glib::RefPtr<Gdk::Pixbuf> tmpPixbuf = Gdk::Pixbuf::create_from_data (ch->cropimg, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, 2 * ch->cropimg_height, 3 * ch->cropimg_width); Glib::RefPtr<Gdk::Pixbuf> tmpPixbuf = Gdk::Pixbuf::create_from_data (ch->cropimg, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, 2 * ch->cropimg_height, 3 * ch->cropimg_width);
ch->cropPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh); ch->cropPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh);
tmpPixbuf->scale (ch->cropPixbuf, 0, 0, imw, imh, 0, 0, czoom / 1000.0, czoom / 1000.0, Gdk::INTERP_NEAREST); tmpPixbuf->scale (ch->cropPixbuf, 0, 0, imw, imh, 0, 0, czoom /* / 1000.0*/, czoom /* / 1000.0*/, Gdk::INTERP_NEAREST);
tmpPixbuf.clear (); tmpPixbuf.clear ();
Glib::RefPtr<Gdk::Pixbuf> tmpPixbuftrue = Gdk::Pixbuf::create_from_data (ch->cropimgtrue, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, 2 * ch->cropimg_height, 3 * ch->cropimg_width); Glib::RefPtr<Gdk::Pixbuf> tmpPixbuftrue = Gdk::Pixbuf::create_from_data (ch->cropimgtrue, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, 2 * ch->cropimg_height, 3 * ch->cropimg_width);
ch->cropPixbuftrue = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh); ch->cropPixbuftrue = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh);
tmpPixbuftrue->scale (ch->cropPixbuftrue, 0, 0, imw, imh, 0, 0, czoom / 1000.0, czoom / 1000.0, Gdk::INTERP_NEAREST); tmpPixbuftrue->scale (ch->cropPixbuftrue, 0, 0, imw, imh, 0, 0, czoom /* / 1000.0*/, czoom /* / 1000.0*/, Gdk::INTERP_NEAREST);
tmpPixbuftrue.clear (); tmpPixbuftrue.clear ();
} }
@ -432,7 +435,7 @@ bool CropHandler::getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip)
cwh = 32; cwh = 32;
} }
cskip = zoom >= 1000 ? 1 : zoom; cskip = zoom >= 1000 ? 1 : zoom/10;
return true; return true;
} }
@ -615,12 +618,12 @@ void CropHandler::compDim ()
scaledCAX = cax * (zoom/1000); scaledCAX = cax * (zoom/1000);
scaledCAY = cay * (zoom/1000); scaledCAY = cay * (zoom/1000);
} else { } else {
wwImgSpace = int(float(ww) * float(zoom) + 0.5f); wwImgSpace = int(float(ww) * (float(zoom)/10.f) + 0.5f);
whImgSpace = int(float(wh) * float(zoom) + 0.5f); whImgSpace = int(float(wh) * (float(zoom)/10.f) + 0.5f);
//scaledFullW = fullW / zoom; //scaledFullW = fullW / zoom;
//scaledFullH = fullH / zoom; //scaledFullH = fullH / zoom;
scaledCAX = cax / zoom; scaledCAX = int(float(cax) / (float(zoom)/10.f));
scaledCAY = cay / zoom; scaledCAY = int(float(cay) / (float(zoom)/10.f));
} }
imgX = ww / 2 - scaledCAX; imgX = ww / 2 - scaledCAX;

View File

@ -34,38 +34,6 @@
using namespace rtengine; using namespace rtengine;
struct ZoomStep {
Glib::ustring label;
double zoom;
int czoom;
};
ZoomStep zoomSteps[] = {
{" 1%", 0.01, 100},
{" 2%", 0.02, 50},
{" 5%", 0.05, 20},
{"6.7%", 1.0 / 15.0, 15},
{" 8%", 1.0 / 12.0, 12},
{" 10%", 0.1, 10},
{"12.5%", 0.125, 8},
{" 14%", 1.0 / 7.0, 7},
{"16.6%", 1.0 / 6.0, 6},
{" 20%", 0.2, 5},
{" 25%", 0.25, 4},
{" 33%", 1.0 / 3.0, 3},
{" 50%", 0.5, 2},
{"100%", 1.0, 1000},
{"200%", 2.0, 2000},
{"300%", 3.0, 3000},
{"400%", 4.0, 4000},
{"500%", 5.0, 5000},
{"600%", 6.0, 6000},
{"700%", 7.0, 7000},
{"800%", 8.0, 8000}
};
#define MAXZOOMSTEPS 20
#define ZOOM11INDEX 13
CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDetailWindow) CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDetailWindow)
: ObjectMOBuffer(parent), state(SNormal), press_x(0), press_y(0), action_x(0), action_y(0), pickedObject(-1), pickModifierKey(0), rot_deg(0), onResizeArea(false), deleted(false), : ObjectMOBuffer(parent), state(SNormal), press_x(0), press_y(0), action_x(0), action_y(0), pickedObject(-1), pickModifierKey(0), rot_deg(0), onResizeArea(false), deleted(false),
fitZoomEnabled(true), fitZoom(false), isLowUpdatePriority(isLowUpdatePriority_), hoveredPicker(nullptr), cropLabel(Glib::ustring("100%")), fitZoomEnabled(true), fitZoom(false), isLowUpdatePriority(isLowUpdatePriority_), hoveredPicker(nullptr), cropLabel(Glib::ustring("100%")),
@ -74,6 +42,8 @@ CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDet
imgX(-1), imgY(-1), imgW(1), imgH(1), iarea(parent), cropZoom(0), zoomVersion(0), exposeVersion(0), cropgl(nullptr), imgX(-1), imgY(-1), imgW(1), imgH(1), iarea(parent), cropZoom(0), zoomVersion(0), exposeVersion(0), cropgl(nullptr),
pmlistener(nullptr), pmhlistener(nullptr), observedCropWin(nullptr) pmlistener(nullptr), pmhlistener(nullptr), observedCropWin(nullptr)
{ {
initZoomSteps();
Glib::RefPtr<Pango::Context> context = parent->get_pango_context () ; Glib::RefPtr<Pango::Context> context = parent->get_pango_context () ;
Pango::FontDescription fontd = context->get_font_description (); Pango::FontDescription fontd = context->get_font_description ();
fontd.set_weight (Pango::WEIGHT_BOLD); fontd.set_weight (Pango::WEIGHT_BOLD);
@ -120,6 +90,37 @@ CropWindow::~CropWindow ()
} }
} }
void CropWindow::initZoomSteps()
{
zoomSteps.push_back(ZoomStep(" 1%", 0.01, 999));
zoomSteps.push_back(ZoomStep(" 2%", 0.02, 500));
zoomSteps.push_back(ZoomStep(" 5%", 0.05, 200));
zoomSteps.push_back(ZoomStep(" 6%", 1.0/15.0, 150));
zoomSteps.push_back(ZoomStep(" 8%", 1.0/12.0, 120));
char lbl[64];
for (int s = 100; s >= 50; s -= 5) {
float z = 10./float(s);
sprintf(lbl, "% 2d%%", int(z * 100));
zoomSteps.push_back(ZoomStep(lbl, z, s));
}
for (int s = 45; s >= 27; s -= 3) {
float z = 10./float(s);
sprintf(lbl, "% 2d%%", int(z * 100));
zoomSteps.push_back(ZoomStep(lbl, z, s));
}
for (int s = 25; s >= 11; --s) {
float z = 10./float(s);
sprintf(lbl, "% 2d%%", int(z * 100));
zoomSteps.push_back(ZoomStep(lbl, z, s));
}
zoom11index = zoomSteps.size();
for (int s = 1; s <= 8; ++s) {
sprintf(lbl, "%d00", s);
zoomSteps.push_back(ZoomStep(lbl, s, s * 1000));
}
}
void CropWindow::enable() void CropWindow::enable()
{ {
cropHandler.setEnabled (true); cropHandler.setEnabled (true);
@ -316,7 +317,7 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y)
state = SNormal; state = SNormal;
zoomVersion = exposeVersion; zoomVersion = exposeVersion;
screenCoordToImage (x, y, action_x, action_y); screenCoordToImage (x, y, action_x, action_y);
changeZoom (ZOOM11INDEX, true, action_x, action_y); changeZoom (zoom11index, true, action_x, action_y);
fitZoom = false; fitZoom = false;
} else { } else {
zoomFit (); zoomFit ();
@ -1967,7 +1968,7 @@ void CropWindow::zoom11 ()
zoomVersion = exposeVersion; zoomVersion = exposeVersion;
} }
changeZoom (ZOOM11INDEX, true, x, y); changeZoom (zoom11index, true, x, y);
fitZoom = false; fitZoom = false;
} }
@ -1984,17 +1985,17 @@ bool CropWindow::isMinZoom ()
bool CropWindow::isMaxZoom () bool CropWindow::isMaxZoom ()
{ {
return cropZoom >= MAXZOOMSTEPS; return cropZoom >= int(zoomSteps.size())-1;
} }
void CropWindow::setZoom (double zoom) void CropWindow::setZoom (double zoom)
{ {
int cz = MAXZOOMSTEPS; int cz = int(zoomSteps.size())-1;
if (zoom < zoomSteps[0].zoom) { if (zoom < zoomSteps[0].zoom) {
cz = 0; cz = 0;
} else } else
for (int i = 0; i < MAXZOOMSTEPS; i++) for (int i = 0; i < int(zoomSteps.size())-1; i++)
if (zoomSteps[i].zoom <= zoom && zoomSteps[i + 1].zoom > zoom) { if (zoomSteps[i].zoom <= zoom && zoomSteps[i + 1].zoom > zoom) {
cz = i; cz = i;
break; break;
@ -2006,12 +2007,12 @@ void CropWindow::setZoom (double zoom)
double CropWindow::getZoomFitVal () double CropWindow::getZoomFitVal ()
{ {
double z = cropHandler.getFitZoom (); double z = cropHandler.getFitZoom ();
int cz = MAXZOOMSTEPS; int cz = int(zoomSteps.size())-1;
if (z < zoomSteps[0].zoom) { if (z < zoomSteps[0].zoom) {
cz = 0; cz = 0;
} else } else
for (int i = 0; i < MAXZOOMSTEPS; i++) for (int i = 0; i < int(zoomSteps.size())-1; i++)
if (zoomSteps[i].zoom <= z && zoomSteps[i + 1].zoom > z) { if (zoomSteps[i].zoom <= z && zoomSteps[i + 1].zoom > z) {
cz = i; cz = i;
break; break;
@ -2025,12 +2026,12 @@ void CropWindow::zoomFit ()
{ {
double z = cropHandler.getFitZoom (); double z = cropHandler.getFitZoom ();
int cz = MAXZOOMSTEPS; int cz = int(zoomSteps.size())-1;
if (z < zoomSteps[0].zoom) { if (z < zoomSteps[0].zoom) {
cz = 0; cz = 0;
} else } else
for (int i = 0; i < MAXZOOMSTEPS; i++) for (int i = 0; i < int(zoomSteps.size())-1; i++)
if (zoomSteps[i].zoom <= z && zoomSteps[i + 1].zoom > z) { if (zoomSteps[i].zoom <= z && zoomSteps[i + 1].zoom > z) {
cz = i; cz = i;
break; break;
@ -2045,12 +2046,12 @@ void CropWindow::zoomFitCrop ()
{ {
if(cropHandler.cropParams.enabled) { if(cropHandler.cropParams.enabled) {
double z = cropHandler.getFitCropZoom (); double z = cropHandler.getFitCropZoom ();
int cz = MAXZOOMSTEPS; int cz = int(zoomSteps.size())-1;
if (z < zoomSteps[0].zoom) { if (z < zoomSteps[0].zoom) {
cz = 0; cz = 0;
} else } else
for (int i = 0; i < MAXZOOMSTEPS; i++) for (int i = 0; i < int(zoomSteps.size())-1; i++)
if (zoomSteps[i].zoom <= z && zoomSteps[i + 1].zoom > z) { if (zoomSteps[i].zoom <= z && zoomSteps[i + 1].zoom > z) {
cz = i; cz = i;
break; break;
@ -2125,8 +2126,8 @@ void CropWindow::changeZoom (int zoom, bool notify, int centerx, int centery)
if (zoom < 0) { if (zoom < 0) {
zoom = 0; zoom = 0;
} else if (zoom > MAXZOOMSTEPS) { } else if (zoom > int(zoomSteps.size())-1) {
zoom = MAXZOOMSTEPS; zoom = int(zoomSteps.size())-1;
} }
cropZoom = zoom; cropZoom = zoom;

View File

@ -114,6 +114,19 @@ class CropWindow : public LWButtonListener, public CropDisplayHandler, public Ed
// Used by the mainCropWindow only // Used by the mainCropWindow only
void getObservedFrameArea (int& x, int& y, int& w, int& h, int rw = 0, int rh = 0); void getObservedFrameArea (int& x, int& y, int& w, int& h, int rw = 0, int rh = 0);
struct ZoomStep {
Glib::ustring label;
double zoom;
int czoom;
explicit ZoomStep(const Glib::ustring &l="", double z=0.0, int cz=0):
label(l), zoom(z), czoom(cz) {}
};
std::vector<ZoomStep> zoomSteps;
size_t zoom11index;
void initZoomSteps();
public: public:
CropHandler cropHandler; CropHandler cropHandler;
CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDetailWindow); CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDetailWindow);