From: dooglus Date: Thu, 13 Nov 2008 19:54:36 +0000 (+0000) Subject: Add an option to the setup dialog "Scale New Imported Images to Fit Canvas". Previou... X-Git-Url: https://git.pterodactylus.net/?a=commitdiff_plain;h=c9582dc1cba08b936b35f36f36c0fa018a203a53;p=synfig.git Add an option to the setup dialog "Scale New Imported Images to Fit Canvas". Previously all imported images were resized to fill the canvas so smaller images were scaled more than bigger ones. When importing PNG files with areas of transparent pixels around the ninja parts, silently ignore as many transparent pixels as possible without affecting the render. This can be disabled by setting environment variable SYNFIG_DISABLE_CROP_IMPORTED_IMAGES. git-svn-id: https://synfig.svn.sourceforge.net/svnroot/synfig@2193 1f10aa63-cdf2-0310-b900-c93c546f37ac --- diff --git a/synfig-core/trunk/src/modules/lyr_std/import.cpp b/synfig-core/trunk/src/modules/lyr_std/import.cpp index a130984..f7385a9 100644 --- a/synfig-core/trunk/src/modules/lyr_std/import.cpp +++ b/synfig-core/trunk/src/modules/lyr_std/import.cpp @@ -162,7 +162,7 @@ Import::set_param(const String & param, const ValueBase &value) } surface.clear(); - if(!newimporter->get_frame(surface,Time(0))) + if(!newimporter->get_frame(surface,Time(0),trimmed,width,height,top,left)) { synfig::warning(strprintf("Unable to get frame from \"%s\"",filename_with_path.c_str())); } @@ -220,15 +220,19 @@ Import::get_param_vocab()const void Import::set_time(Context context, Time time)const { - if(get_amount() && importer && importer->is_animated())importer->get_frame(surface,time+time_offset); - //else surface.clear(); + if(get_amount() && importer && + importer->is_animated()) + importer->get_frame(surface,time+time_offset,trimmed,width,height,top,left); + context.set_time(time); } void Import::set_time(Context context, Time time, const Point &pos)const { - if(get_amount() && importer && importer->is_animated())importer->get_frame(surface,time+time_offset); - //else surface.clear(); + if(get_amount() && importer && + importer->is_animated()) + importer->get_frame(surface,time+time_offset,trimmed,width,height,top,left); + context.set_time(time,pos); } diff --git a/synfig-core/trunk/src/modules/mod_png/mptr_png.cpp b/synfig-core/trunk/src/modules/mod_png/mptr_png.cpp index f0fcb86..641ee82 100644 --- a/synfig-core/trunk/src/modules/mod_png/mptr_png.cpp +++ b/synfig-core/trunk/src/modules/mod_png/mptr_png.cpp @@ -217,15 +217,14 @@ png_mptr::png_mptr(const char *file_name) png_read_image(png_ptr, row_pointers); - int x; - int y; + png_uint_32 x, y; surface_buffer.set_wh(width,height); switch(color_type) { case PNG_COLOR_TYPE_RGB: - for(y=0;ypalette[row_pointers[y][x]].red); float g=gamma().g_U8_to_F32((unsigned char)png_ptr->palette[row_pointers[y][x]].green); @@ -333,6 +332,75 @@ png_mptr::png_mptr(const char *file_name) delete [] row_pointers; delete [] data; + + trim = false; + + if (getenv("SYNFIG_DISABLE_CROP_IMPORTED_IMAGES")) + return; + + switch(color_type) + { + case PNG_COLOR_TYPE_RGB_ALPHA: + case PNG_COLOR_TYPE_GRAY_ALPHA: + case PNG_COLOR_TYPE_PALETTE: + for(y=0;yBORDER) min_y = y-BORDER; else min_y = 0; + + for(y=height-1;y>0;y--) + { + for(x=0;xBORDER) min_x = x-BORDER; else min_x = 0; + + for(x=width-1;x>0;x--) + { + for(y=0;y /* === S Y N F I G ========================================================= */ /*! \file importer.h ** \brief writeme @@ -108,6 +109,13 @@ public: ** \see ProgressCallback, Surface */ virtual bool get_frame(Surface &surface,Time time, ProgressCallback *callback=NULL)=0; + virtual bool get_frame(Surface &surface,Time time, + bool &trimmed __attribute__ ((unused)), + unsigned int &width __attribute__ ((unused)), unsigned int &height __attribute__ ((unused)), + unsigned int &top __attribute__ ((unused)), unsigned int &left __attribute__ ((unused)), + ProgressCallback *callback=NULL) { + return get_frame(surface,time,callback); + } //! Returns \c true if the importer pays attention to the \a time parameter of get_frame() virtual bool is_animated() { return false; } diff --git a/synfig-core/trunk/src/synfig/layer_bitmap.cpp b/synfig-core/trunk/src/synfig/layer_bitmap.cpp index e84dade..fc395dc 100644 --- a/synfig-core/trunk/src/synfig/layer_bitmap.cpp +++ b/synfig-core/trunk/src/synfig/layer_bitmap.cpp @@ -68,6 +68,7 @@ synfig::Layer_Bitmap::Layer_Bitmap(): br (0.5,-0.5), c (1), surface (128,128), + trimmed (false), gamma_adjust (1.0) { } @@ -99,10 +100,12 @@ synfig::Layer_Bitmap::get_param(const String & param)const if(param=="_width") { + if (trimmed) return int(width); return surface.get_w(); } if(param=="_height") { + if (trimmed) return int(height); return surface.get_h(); } @@ -191,8 +194,22 @@ synfig::Layer_Bitmap::get_color(Context context, const Point &pos)const surface_pos[1]/=br[1]-tl[1]; if(surface_pos[1]<=1.0 && surface_pos[1]>=0.0) { - surface_pos[0]*=surface.get_w(); - surface_pos[1]*=surface.get_h(); + if (trimmed) + { + surface_pos[0]*=width; + surface_pos[1]*=height; + + if (surface_pos[0] > left+surface.get_w() || surface_pos[0] < left || surface_pos[1] > top+surface.get_h() || surface_pos[1] < top) + return context.get_color(pos); + + surface_pos[0] -= left; + surface_pos[1] -= top; + } + else + { + surface_pos[0]*=surface.get_w(); + surface_pos[1]*=surface.get_h(); + } Color ret(Color::alpha()); @@ -257,6 +274,7 @@ Layer_Bitmap::accelerated_render(Context context,Surface *out_surface,int qualit if( get_amount()==1 && get_blend_method()==Color::BLEND_STRAIGHT && + !trimmed && renddesc.get_tl()==tl && renddesc.get_br()==br) { @@ -290,9 +308,6 @@ Layer_Bitmap::accelerated_render(Context context,Surface *out_surface,int qualit //sa = scaling for input (0,1) -> (0,w/h) //sb = scaling for output (0,1) -> (0,w/h) - float inwf = br[0] - tl[0]; - float inhf = br[1] - tl[1]; - float outwf = obr[0] - otl[0]; float outhf = obr[1] - otl[1]; @@ -302,14 +317,34 @@ Layer_Bitmap::accelerated_render(Context context,Surface *out_surface,int qualit int outw = renddesc.get_w(); int outh = renddesc.get_h(); + float inwf, inhf; + Point itl, ibr; + + if (trimmed) + { + inwf = (br[0] - tl[0])*surface.get_w()/width; + inhf = (br[1] - tl[1])*surface.get_h()/height; + itl = Point(tl[0] + (br[0]-tl[0])*left/width, + tl[1] + (br[1]-tl[1])*top/height); + ibr = Point(tl[0] + (br[0]-tl[0])*(left+inw)/width, + tl[1] + (br[1]-tl[1])*(top+inh)/height); + } + else + { + inwf = br[0] - tl[0]; + inhf = br[1] - tl[1]; + itl = tl; + ibr = br; + } + //need to get the input coords in output space, so we can clip //get the desired corners of the bitmap (in increasing order) in integers //floating point corners - float x1f = (tl[0] - otl[0])*outw/outwf; - float x2f = (br[0] - otl[0])*outw/outwf; - float y1f = (tl[1] - otl[1])*outh/outhf; - float y2f = (br[1] - otl[1])*outh/outhf; + float x1f = (itl[0] - otl[0])*outw/outwf; + float x2f = (ibr[0] - otl[0])*outw/outwf; + float y1f = (itl[1] - otl[1])*outh/outhf; + float y2f = (ibr[1] - otl[1])*outh/outhf; if(x1f > x2f) swap(x1f,x2f); if(y1f > y2f) swap(y1f,y2f); @@ -325,8 +360,8 @@ Layer_Bitmap::accelerated_render(Context context,Surface *out_surface,int qualit // in int -> out float: // Sb(B^-1)A(Sa^-1) x - float inx_start = (((x_start/*+0.5f*/)*outwf/outw + otl[0]) - tl[0])*inw/inwf; //may want to bias this (center of pixel)??? - float iny_start = (((y_start/*+0.5f*/)*outhf/outh + otl[1]) - tl[1])*inh/inhf; //may want to bias this (center of pixel)??? + float inx_start = (((x_start/*+0.5f*/)*outwf/outw + otl[0]) - itl[0])*inw/inwf; //may want to bias this (center of pixel)??? + float iny_start = (((y_start/*+0.5f*/)*outhf/outh + otl[1]) - itl[1])*inh/inhf; //may want to bias this (center of pixel)??? //calculate the delta values in input space for one pixel movement in output space //same matrix but with a vector instead of a point... diff --git a/synfig-core/trunk/src/synfig/layer_bitmap.h b/synfig-core/trunk/src/synfig/layer_bitmap.h index c313321..4669092 100644 --- a/synfig-core/trunk/src/synfig/layer_bitmap.h +++ b/synfig-core/trunk/src/synfig/layer_bitmap.h @@ -51,6 +51,8 @@ public: Point br; int c; mutable Surface surface; + mutable bool trimmed; + mutable unsigned int width, height, top, left; Real gamma_adjust; diff --git a/synfig-studio/trunk/src/gtkmm/app.cpp b/synfig-studio/trunk/src/gtkmm/app.cpp index d59c3b0..7ea2e74 100644 --- a/synfig-studio/trunk/src/gtkmm/app.cpp +++ b/synfig-studio/trunk/src/gtkmm/app.cpp @@ -275,6 +275,7 @@ bool studio::App::use_colorspace_gamma=true; bool studio::App::single_threaded=false; #endif bool studio::App::restrict_radius_ducks=false; +bool studio::App::resize_imported_images=false; String studio::App::custom_filename_prefix(DEFAULT_FILENAME_PREFIX); int studio::App::preferred_x_size=480; int studio::App::preferred_y_size=270; @@ -511,6 +512,11 @@ public: value=strprintf("%i",(int)App::restrict_radius_ducks); return true; } + if(key=="resize_imported_images") + { + value=strprintf("%i",(int)App::resize_imported_images); + return true; + } if(key=="browser_command") { value=App::browser_command; @@ -600,6 +606,12 @@ public: App::restrict_radius_ducks=i; return true; } + if(key=="resize_imported_images") + { + int i(atoi(value.c_str())); + App::resize_imported_images=i; + return true; + } if(key=="browser_command") { App::browser_command=value; @@ -643,6 +655,7 @@ public: #endif ret.push_back("auto_recover_backup_interval"); ret.push_back("restrict_radius_ducks"); + ret.push_back("resize_imported_images"); ret.push_back("browser_command"); ret.push_back("custom_filename_prefix"); ret.push_back("preferred_x_size"); @@ -1732,6 +1745,7 @@ App::reset_initial_window_configuration() synfigapp::Main::settings().set_value("pref.single_threaded","0"); #endif synfigapp::Main::settings().set_value("pref.restrict_radius_ducks","0"); + synfigapp::Main::settings().set_value("pref.resize_imported_images","0"); synfigapp::Main::settings().set_value("pref.custom_filename_prefix",DEFAULT_FILENAME_PREFIX); synfigapp::Main::settings().set_value("pref.preferred_x_size","480"); synfigapp::Main::settings().set_value("pref.preferred_y_size","270"); diff --git a/synfig-studio/trunk/src/gtkmm/app.h b/synfig-studio/trunk/src/gtkmm/app.h index d1c4e3b..507bc75 100644 --- a/synfig-studio/trunk/src/gtkmm/app.h +++ b/synfig-studio/trunk/src/gtkmm/app.h @@ -197,6 +197,7 @@ public: #endif static bool restrict_radius_ducks; + static bool resize_imported_images; static synfig::String browser_command; static synfig::String custom_filename_prefix; diff --git a/synfig-studio/trunk/src/gtkmm/canvasview.cpp b/synfig-studio/trunk/src/gtkmm/canvasview.cpp index 18cfb43..a9bda67 100644 --- a/synfig-studio/trunk/src/gtkmm/canvasview.cpp +++ b/synfig-studio/trunk/src/gtkmm/canvasview.cpp @@ -3461,7 +3461,7 @@ CanvasView::on_drop_drag_data_received(const Glib::RefPtr& con } else { - if(canvas_interface()->import(filename)) + if(canvas_interface()->import(filename, App::resize_imported_images)) success=true; } @@ -3570,7 +3570,7 @@ CanvasView::image_import() // String filename(dirname(get_canvas()->get_file_name())); String filename("*.*"); if(App::dialog_open_file(_("Import Image"), filename, IMAGE_DIR_PREFERENCE)) - canvas_interface()->import(filename); + canvas_interface()->import(filename, App::resize_imported_images); } Smach::event_result diff --git a/synfig-studio/trunk/src/gtkmm/dialog_setup.cpp b/synfig-studio/trunk/src/gtkmm/dialog_setup.cpp index 9b7dcd4..9080d65 100644 --- a/synfig-studio/trunk/src/gtkmm/dialog_setup.cpp +++ b/synfig-studio/trunk/src/gtkmm/dialog_setup.cpp @@ -82,6 +82,7 @@ Dialog_Setup::Dialog_Setup(): toggle_single_threaded(_("Use Only a Single Thread")), #endif toggle_restrict_radius_ducks(_("Restrict Real-Valued Ducks to Top Right Quadrant")), + toggle_resize_imported_images(_("Scale New Imported Images to Fit Canvas")), adj_pref_x_size(480,1,10000,1,10,0), adj_pref_y_size(270,1,10000,1,10,0) @@ -210,6 +211,9 @@ Dialog_Setup::Dialog_Setup(): // Misc - restrict_radius_ducks misc_table->attach(toggle_restrict_radius_ducks, 0, 2, 8, 9, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, xpadding, ypadding); + // Misc - resize_imported_images + misc_table->attach(toggle_resize_imported_images, 0, 2, 9, 10, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, xpadding, ypadding); + // Misc - browser_command attach_label(misc_table, _("Browser Command"), 4, xpadding, ypadding); misc_table->attach(textbox_browser_command, 1, 2, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, xpadding, ypadding); @@ -298,6 +302,9 @@ Dialog_Setup::on_apply_pressed() // Set the restrict_radius_ducks flag App::restrict_radius_ducks=toggle_restrict_radius_ducks.get_active(); + // Set the resize_imported_images flag + App::resize_imported_images=toggle_resize_imported_images.get_active(); + // Set the browser_command textbox App::browser_command=textbox_browser_command.get_text(); @@ -415,6 +422,9 @@ Dialog_Setup::refresh() // Refresh the status of the restrict_radius_ducks flag toggle_restrict_radius_ducks.set_active(App::restrict_radius_ducks); + // Refresh the status of the resize_imported_images flag + toggle_resize_imported_images.set_active(App::resize_imported_images); + // Refresh the browser_command textbox textbox_browser_command.set_text(App::browser_command); diff --git a/synfig-studio/trunk/src/gtkmm/dialog_setup.h b/synfig-studio/trunk/src/gtkmm/dialog_setup.h index c97e834..483d211 100644 --- a/synfig-studio/trunk/src/gtkmm/dialog_setup.h +++ b/synfig-studio/trunk/src/gtkmm/dialog_setup.h @@ -182,6 +182,7 @@ class Dialog_Setup : public Gtk::Dialog Widget_Time auto_backup_interval; Gtk::CheckButton toggle_restrict_radius_ducks; + Gtk::CheckButton toggle_resize_imported_images; Gtk::Entry textbox_browser_command; diff --git a/synfig-studio/trunk/src/synfigapp/canvasinterface.cpp b/synfig-studio/trunk/src/synfigapp/canvasinterface.cpp index d3d96c7..ca4c651 100644 --- a/synfig-studio/trunk/src/synfigapp/canvasinterface.cpp +++ b/synfig-studio/trunk/src/synfigapp/canvasinterface.cpp @@ -560,7 +560,7 @@ CanvasInterface::jump_to_prev_keyframe() } bool -CanvasInterface::import(const synfig::String &filename, bool /*copy*/) +CanvasInterface::import(const synfig::String &filename, bool resize_image) { Action::PassiveGrouper group(get_instance().get(),_("Import Image")); @@ -623,22 +623,34 @@ CanvasInterface::import(const synfig::String &filename, bool /*copy*/) h=layer->get_param("_height").get(int()); if(w&&h) { - Vector size=ValueBase(get_canvas()->rend_desc().get_br()-get_canvas()->rend_desc().get_tl()); - Vector x; - if(size[0]rend_desc().get_br()-get_canvas()->rend_desc().get_tl()); + + // vector from top left of canvas to bottom right + if (resize_image) { - x[0]=size[0]; - x[1]=size[0]/w*h; - if((size[0]<0) ^ (size[1]<0)) - x[1]=-x[1]; + if(abs(size[0])set_param("tl",ValueBase(-x/2))) throw int(); if(!layer->set_param("br",ValueBase(x/2))) diff --git a/synfig-studio/trunk/src/synfigapp/canvasinterface.h b/synfig-studio/trunk/src/synfigapp/canvasinterface.h index 1d82f05..21f9a14 100644 --- a/synfig-studio/trunk/src/synfigapp/canvasinterface.h +++ b/synfig-studio/trunk/src/synfigapp/canvasinterface.h @@ -271,7 +271,7 @@ public: void set_rend_desc(const synfig::RendDesc &rend_desc); - bool import(const synfig::String &filename, bool copy=false); + bool import(const synfig::String &filename, bool resize_image=false); void waypoint_duplicate(synfigapp::ValueDesc value_desc,synfig::Waypoint waypoint);