Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions src/iv/imageviewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <OpenImageIO/color.h>
#include <OpenImageIO/dassert.h>
#include <OpenImageIO/filesystem.h>
#include <OpenImageIO/imagebufalgo.h>
#include <OpenImageIO/imagecache.h>
#include <OpenImageIO/strutil.h>
#include <OpenImageIO/sysutil.h>
Expand Down Expand Up @@ -1104,13 +1105,31 @@ ImageViewer::saveWindowAs()
IvImage* img = cur();
if (!img)
return;
ROI roi;
glwin->get_visible_image_roi(roi);
if (!roi.defined() || roi.width() <= 0 || roi.height() <= 0) {
// TODO: May not be visible. This should be replaced with a GUI dialog.
OIIO::print(stderr,
"Save failed: no pixels of the image are visible\n");
return;
}
QString name;
name = QFileDialog::getSaveFileName(this, tr("Save Window"),
QString(img->uname().c_str()));
if (name.isEmpty())
return;
img->write(name.toStdString(), TypeUnknown, "", image_progress_callback,
this);
ImageBuf cropped;
if (!ImageBufAlgo::cut(cropped, *img, roi)) {
// TODO: May not be visible. This should be replaced with a GUI dialog.
OIIO::print(stderr, "Crop failed: {}\n", cropped.geterror());
return;
}
bool ok = cropped.write(name.toStdString(), TypeUnknown, "",
image_progress_callback, this);
if (!ok) {
// TODO: May not be visible. This should be replaced with a GUI dialog.
OIIO::print(stderr, "Save failed: {}\n", cropped.geterror());
}
}


Expand Down
35 changes: 35 additions & 0 deletions src/iv/ivgl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2186,6 +2186,41 @@ IvGL::get_given_image_pixel(int& x, int& y, int mouseX, int mouseY)



void
IvGL::get_visible_image_roi(ROI& roi)
{
roi = ROI();
IvImage* img = m_slots[0].image;
if (!img || !img->image_valid())
return;
const ImageSpec& spec(img->spec());

// The two opposite corners of the viewport, in image pixel coordinates
int x0, y0, x1, y1;
get_given_image_pixel(x0, y0, 0, 0);
get_given_image_pixel(x1, y1, width() - 1, height() - 1);

// Rotating or flipping the display may send the corners anywhere, so map
// both of them and then sort out which is the min and which is the max.
float scale_x = 1.0f, scale_y = 1.0f, rotate_z = 0.0f;
float x0_img = x0, y0_img = y0, x1_img = x1, y1_img = y1;
handle_orientation(img->orientation(), spec.width, spec.height, scale_x,
scale_y, rotate_z, x0_img, y0_img, true);
handle_orientation(img->orientation(), spec.width, spec.height, scale_x,
scale_y, rotate_z, x1_img, y1_img, true);

ROI visible((int)floorf(std::min(x0_img, x1_img)),
(int)floorf(std::max(x0_img, x1_img)) + 1,
(int)floorf(std::min(y0_img, y1_img)),
(int)floorf(std::max(y0_img, y1_img)) + 1, 0, 1, 0,
spec.nchannels);

// The window may show more than the image, so keep only real pixels.
roi = roi_intersection(visible, img->roi());
}



void
IvGL::get_focus_image_pixel(int& x, int& y)
{
Expand Down
4 changes: 4 additions & 0 deletions src/iv/ivgl.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ class IvGL : public QOpenGLWidget, protected QOpenGLExtraFunctions {
///
void get_given_image_pixel(int& x, int& y, int mouseX, int mouseY);

/// Which region of the current image is currently visible in the
/// viewport?
void get_visible_image_roi(ROI& roi);

/// What are the min/max/avg values of each channel in the selected area?
void update_area_probe_text();

Expand Down
Loading