/** * Rotate an image. Valid options are degrees * * @param string $input_file * @param string $output_file * @param array $options */ static function rotate($input_file, $output_file, $options) { graphics::init_toolkit(); module::event("graphics_rotate", $input_file, $output_file, $options); // BEGIN mod to original function $image_info = getimagesize($input_file); // [0]=w, [1]=h, [2]=type (1=GIF, 2=JPG, 3=PNG) if (module::get_var("image_optimizer", "rotate_jpg") || $image_info[2] == 2) { // rotate_jpg enabled, the file is a jpg. get args $path = module::get_var("image_optimizer", "path_jpg"); $exec_args = " -rotate "; $exec_args .= $options["degrees"] > 0 ? $options["degrees"] : $options["degrees"] + 360; $exec_args .= " -copy all -optimize -outfile "; // run it - from input_file to tmp_file $tmp_file = image_optimizer::make_temp_name($output_file); exec(escapeshellcmd($path) . $exec_args . escapeshellarg($tmp_file) . " " . escapeshellarg($input_file), $exec_output, $exec_status); if ($exec_status || !filesize($tmp_file)) { // either a blank/nonexistant file or an error - log an error and pass to normal function Kohana_Log::add("error", "image_optimizer rotation failed on " . $output_file); unlink($tmp_file); } else { // worked - move temp to output rename($tmp_file, $output_file); $status = true; } } if (!$status) { // we got here if we weren't supposed to use jpegtran or if jpegtran failed // END mod to original function Image::factory($input_file)->quality(module::get_var("gallery", "image_quality"))->rotate($options["degrees"])->save($output_file); // BEGIN mod to original function } // END mod to original function module::event("graphics_rotate_completed", $input_file, $output_file, $options); }
static function deactivate() { // ensure that update modes are disabled image_optimizer::deactivate_update_mode("thumb"); image_optimizer::deactivate_update_mode("resize"); // remove graphics rules image_optimizer::remove_image_optimizer_rule("thumb"); image_optimizer::remove_image_optimizer_rule("resize"); }
private function _get_admin_form() { $form = new Forge("admin/image_optimizer/save", "", "post", array("id" => "g-image-optimizer-admin-form")); $group_paths = $form->group("paths")->label(t("Toolkit paths"))->set_attr("id", "g-image-optimizer-admin-form-paths"); foreach (array('jpg', 'png', 'gif') as $type) { $path = strval(module::get_var("image_optimizer", "path_" . $type, null)); $group_paths->input("path_" . $type)->label(t("Path for") . " " . image_optimizer::tool_name($type) . " (" . t("no symlinks, default") . " " . MODPATH . "image_optimizer/lib/" . image_optimizer::tool_name($type) . ")")->value($path); } $group_rotate = $form->group("rotate")->label(t("Full-size image rotation"))->set_attr("id", "g-image-optimizer-admin-form-rotate"); $group_rotate->checkbox("rotate_jpg")->label(t("Override default toolkit and use") . " " . image_optimizer::tool_name('jpg') . " " . t("for rotation"))->checked(module::get_var("image_optimizer", "rotate_jpg", null)); foreach (array('thumb', 'resize') as $target) { ${'group_' . $target} = $form->group($target)->label(ucfirst($target) . " " . t("images optimization"))->set_attr("id", "g-image-optimizer-admin-form-" . $target); ${'group_' . $target}->checkbox("enable_" . $target)->label(t("Enable optimization"))->checked(module::get_var("image_optimizer", "enable_" . $target, null)); ${'group_' . $target}->checkbox("update_mode_" . $target)->label(t("Enable update mode - deactivates all other graphics rules to allow fast optimization on existing images; MUST deactivate this after initial rebuild!"))->checked(module::get_var("image_optimizer", "update_mode_" . $target, null)); ${'group_' . $target}->checkbox("rebuild_" . $target)->label(t("Mark all existing images for rebuild - afterward, go to Maintenace | Rebuild Images"))->checked(false); // always set as false ${'group_' . $target}->dropdown("convert_" . $target . "_png")->label(t("PNG conversion"))->options(array(0 => t("none"), "jpg" => "JPG " . t("(not lossless)")))->selected(module::get_var("image_optimizer", "convert_" . $target . "_png", null)); ${'group_' . $target}->dropdown("convert_" . $target . "_gif")->label(t("GIF conversion"))->options(array(0 => t("none"), "jpg" => "JPG " . t("(not lossless)"), "png" => "PNG " . t("(lossless)")))->selected(module::get_var("image_optimizer", "convert_" . $target . "_gif", null)); ${'group_' . $target}->dropdown("optlevel_" . $target . "_jpg")->label(t("JPG compression optimization (default: enabled)"))->options(array(0 => t("disabled"), 1 => t("enabled")))->selected(module::get_var("image_optimizer", "optlevel_" . $target . "_jpg", null)); ${'group_' . $target}->dropdown("optlevel_" . $target . "_png")->label(t("PNG compression optimization (default: level 2)"))->options(array(0 => t("disabled"), 1 => t("level 1: 1 trial"), 2 => t("level 2: 8 trials"), 3 => t("level 3: 16 trials"), 4 => t("level 4: 24 trials"), 5 => t("level 5: 48 trials"), 6 => t("level 6: 120 trials"), 7 => t("level 7: 240 trials")))->selected(module::get_var("image_optimizer", "optlevel_" . $target . "_png", null)); ${'group_' . $target}->dropdown("optlevel_" . $target . "_gif")->label(t("GIF compression optimization (default: enabled)"))->options(array(0 => t("disabled"), 1 => t("enabled")))->selected(module::get_var("image_optimizer", "optlevel_" . $target . "_gif", null)); ${'group_' . $target}->checkbox("metastrip_" . $target)->label(t("Remove all meta data"))->checked(module::get_var("image_optimizer", "metastrip_" . $target, null)); ${'group_' . $target}->checkbox("progressive_" . $target)->label(t("Make images progressive/interlaced"))->checked(module::get_var("image_optimizer", "progressive_" . $target, null)); } $form->submit("")->value(t("Save")); return $form; }
/** * the main optimize function * * the function arguments are the same format as other graphics rules. the only "option" is $target, hence why it's renamed in the function def. * * NOTE: unlike other graphics transformations, this only uses the output file! if it isn't already there, we don't do anything. * among other things, this means that the original, full-size images are never touched. */ static function optimize($input_file, $output_file, $target, $item = null) { // see if output file exists and is writable if (is_writable($output_file)) { // see if input is a supported file type. if not, return without doing anything. $image_info = getimagesize($input_file); // [0]=w, [1]=h, [2]=type (1=GIF, 2=JPG, 3=PNG) switch ($image_info[2]) { case 1: $type_old = "gif"; $convert = module::get_var("image_optimizer", "convert_" . $target . "_gif"); break; case 2: $type_old = "jpg"; $convert = 0; // no conversion possible here... break; case 3: $type_old = "png"; $convert = module::get_var("image_optimizer", "convert_" . $target . "_png"); break; default: // not a supported file type return; } } else { // file doesn't exist or isn't writable return; } // set new file type $type = $convert ? $convert : $type_old; // convert image type (if applicable). this isn't necessarily lossless. if ($convert) { $output_file_new = legal_file::change_extension($output_file, $type); // perform conversion using standard Gallery toolkit (GD/ImageMagick/GraphicsMagick) // note: if input was a GIF, this will kill animation $image = Image::factory($output_file)->quality(module::get_var("gallery", "image_quality"))->save($output_file_new); // if filenames are different, move the new on top of the old if ($output_file != $output_file_new) { /** * HACK ALERT! Gallery3 is still broken with regard to treating thumb/resizes with proper extensions. This doesn't try to fix that. * Normal Gallery setup: * photo thumb -> keep photo type, keep photo extension * album thumb -> keep source photo thumb type, change extension to jpg (i.e. ".album.jpg" even for png/gif) * Also, missing_photo.png is similarly altered... * * Anyway, to avoid many rewrites of core functions (and not-easily-reversible database changes), this module also forces the extension to stay the same. * With image optimizer conversion: * photo thumb -> change type, keep photo extension (i.e. "photo.png" photo becomes "photo.png" thumb even if type has changed) * album thumb -> keep source photo thumb type, change extension to jpg (i.e. ".album.jpg" even for png/gif) */ rename($output_file_new, $output_file); } } // get module variables $configstatus = module::get_var("image_optimizer", "configstatus_" . $type); $path = module::get_var("image_optimizer", "path_" . $type); $opt = module::get_var("image_optimizer", "optlevel_" . $target . "_" . $type); $meta = module::get_var("image_optimizer", "metastrip_" . $target); $prog = module::get_var("image_optimizer", "progressive_" . $target); // make sure the toolkit is configured correctly and we want to use it - if not, return without doing anything. if ($configstatus) { if (!$prog && !$meta && !$opt) { // nothing to do! return; } } else { // not configured correctly return; } /** * do the actual optimization */ // set parameters switch ($type) { case "jpg": $exec_args = $opt ? " -optimize" : ""; $exec_args .= $meta ? " -copy none" : " -copy all"; $exec_args .= $prog ? " -progressive" : ""; $exec_args .= " -outfile "; break; case "png": $exec_args = $opt ? " -o" . $opt : ""; $exec_args .= $meta ? " -strip all" : ""; $exec_args .= $prog ? " -i 1" : ""; $exec_args .= " -quiet -out "; break; case "gif": $exec_args = $opt ? " --optimize=3" : ""; // levels 1 and 2 don't really help us $exec_args .= $meta ? " --no-comments --no-extensions --no-names" : " --same-comments --same-extensions --same-names"; $exec_args .= $prog ? " --interlace" : " --same-interlace"; $exec_args .= " --careful --output "; break; } // run it - from output_file to tmp_file. $tmp_file = image_optimizer::make_temp_name($output_file); exec(escapeshellcmd($path) . $exec_args . escapeshellarg($tmp_file) . " " . escapeshellarg($output_file), $exec_output, $exec_status); if ($exec_status || !filesize($tmp_file)) { // either a blank/nonexistant file or an error - do nothing to the output, but log an error and delete the temp (if any) Kohana_Log::add("error", "image_optimizer optimization failed on " . $output_file); unlink($tmp_file); } else { // worked - move temp to output rename($tmp_file, $output_file); } }