[pdfmod] Export images (jpg/png) is now working



commit 3280d4ad003ec3498bac642be7a9d1c524caa2db
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Mon Aug 3 18:28:37 2009 -0700

    Export images (jpg/png) is now working

 src/PdfMod/PdfMod.Actions/ExportImagesAction.cs |   43 +++++++++++++----------
 src/PdfMod/PdfMod/GlobalActions.cs              |   23 ++++++------
 src/PdfMod/Resources/UIManager.xml              |    9 +++--
 3 files changed, 41 insertions(+), 34 deletions(-)
---
diff --git a/src/PdfMod/PdfMod.Actions/ExportImagesAction.cs b/src/PdfMod/PdfMod.Actions/ExportImagesAction.cs
index febd346..18f089d 100644
--- a/src/PdfMod/PdfMod.Actions/ExportImagesAction.cs
+++ b/src/PdfMod/PdfMod.Actions/ExportImagesAction.cs
@@ -49,7 +49,7 @@ namespace PdfMod.Actions
 
         public ExportImagesAction (Document document, IEnumerable<Page> pages)
         {
-            image_objects = GetImageObjects (pages).Where (IsExportable).ToList ();
+            image_objects = GetImageObjectsFrom (pages).Where (IsExportable).ToList ();
         }
 
         public int ExportableImageCount {
@@ -63,16 +63,19 @@ namespace PdfMod.Actions
             }
         }
 
-        private IEnumerable<ImageInfo> GetImageObjects (IEnumerable<Page> pages)
+        private IEnumerable<ImageInfo> GetImageObjectsFrom (IEnumerable<Page> pages)
         {
-            foreach (var page in pages) {
+            // Doesn't seem like you can get the images just on one page; the following
+            // gets all the images in the whole document, so only need to do it from one page
+            //foreach (var page in pages) {
+                var page = pages.First ();
                 var resources = page.Pdf.Elements.GetDictionary ("/Resources");
                 if (resources == null)
-                    continue;
+                    yield break;
 
                 var x_objects = resources.Elements.GetDictionary ("/XObject");
                 if (x_objects == null)
-                    continue;
+                    yield break;
 
                 int i = 0;
                 var items = x_objects.Elements.Values;
@@ -88,13 +91,12 @@ namespace PdfMod.Actions
                         yield return new ImageInfo () { Page = page, ImageObject = x_object, PageIndex = i++ };
                     }
                 }
-            }
+            //}
         }
 
         private bool IsExportable (ImageInfo image)
         {
             var filter = image.ImageObject.Elements.GetName("/Filter");
-            Console.WriteLine ("Have image of type: {0}", filter);
             return filter == "/DCTDecode" || filter == "/FlateDecode";
         }
 
@@ -106,23 +108,26 @@ namespace PdfMod.Actions
             string filter = image.ImageObject.Elements.GetName("/Filter");
             switch (filter) {
             case "/DCTDecode":
-                ExportJpegImage (image, GetFilename (image, to_path));
+                ExportJpegImage (image, GetFilename (image, to_path, "jpg"));
                 break;
             case "/FlateDecode":
-                ExportAsPngImage (image, GetFilename (image, to_path));
+                ExportAsPngImage (image, GetFilename (image, to_path, "png"));
                 break;
             }
         }
 
-        private static string GetFilename (ImageInfo image, string to_path)
+        private static string GetFilename (ImageInfo image, string to_path, string ext)
         {
             var name = image.ImageObject.Elements.GetName ("/Name");
             var name_fragment = String.IsNullOrEmpty (name) ? null : String.Format (" ({0})", name);
-            return Path.Combine (
-                Path.GetDirectoryName (to_path),
-                String.Format ("Page {0} - #{1:00}{2}.jpeg",
-                    image.Page.Index, image.PageIndex, name_fragment)
+            var path = Path.Combine (
+                to_path,
+                String.Format ("{0:00}{1}.{2}",
+                    image.PageIndex, name_fragment, ext)
+                //String.Format ("Page {0} - #{1:00}{2}.{3}",
+                    //image.Page.Index, image.PageIndex, name_fragment, ext)
             );
+            return path;
         }
 
         /// <summary>
@@ -140,18 +145,18 @@ namespace PdfMod.Actions
         }
 
         /// <summary>
-        /// Exports image in PNF format.
+        /// Exports image in PNG format.
         /// </summary>
         static void ExportAsPngImage (ImageInfo image, string path)
         {
             int width = image.ImageObject.Elements.GetInteger (PdfImage.Keys.Width);
             int height = image.ImageObject.Elements.GetInteger (PdfImage.Keys.Height);
 
-            var decoder = new PdfSharp.Pdf.Filters.FlateDecode ();
             try {
-                byte[] data = decoder.Decode (image.ImageObject.Stream.Value);
-                Gdk.Pixbuf pixbuf = new Gdk.Pixbuf (data, width, height);
-                pixbuf.Save (path, "png");
+                byte [] data = image.ImageObject.Stream.UnfilteredValue;
+                using (var pixbuf = new Gdk.Pixbuf (data, Gdk.Colorspace.Rgb, false, 8, width, height, width*3)) {
+                    pixbuf.Save (path, "png");
+                }
             } catch (Exception e) {
                 Hyena.Log.Exception ("Unable to load PNG from embedded PDF object", e);
             }
diff --git a/src/PdfMod/PdfMod/GlobalActions.cs b/src/PdfMod/PdfMod/GlobalActions.cs
index 4094996..0f5b63a 100644
--- a/src/PdfMod/PdfMod/GlobalActions.cs
+++ b/src/PdfMod/PdfMod/GlobalActions.cs
@@ -25,12 +25,11 @@ namespace PdfMod
 
         private static string [] require_doc_actions = new string[] {
             "SaveAction", "SaveAsAction", "PropertiesAction", "UndoAction", "RedoAction", "ZoomFitAction",
-            "SelectAllAction", "SelectEvensAction", "SelectOddsAction", "SelectMatchingAction", "InsertFromAction"
+            "SelectAllAction", "SelectEvensAction", "SelectOddsAction", "SelectMatchingAction", "InsertFromAction", "ExportImagesAction"
         };
 
         private static string [] require_page_actions = new string[] {
             "RemoveAction", "ExtractAction", "RotateRightAction", "RotateLeftAction"
-            //, "ExportImagesAction"
         };
 
         public UndoManager UndoManager {
@@ -55,7 +54,7 @@ namespace PdfMod
                 new ActionEntry ("ExtractAction", Gtk.Stock.New, null, null, null, OnExtractPages),
                 new ActionEntry ("RotateRightAction", null, Catalog.GetString ("Rotate Right"), "bracketright", Catalog.GetString ("Rotate right"), OnRotateRight),
                 new ActionEntry ("RotateLeftAction", null, Catalog.GetString ("Rotate Left"), "bracketleft", Catalog.GetString ("Rotate left"), OnRotateLeft),
-                new ActionEntry ("ExportImagesAction", null, Catalog.GetString ("Export Images..."), null, null, OnExportImages),
+                new ActionEntry ("ExportImagesAction", null, Catalog.GetString ("Export Images"), null, Catalog.GetString ("Save all images in this document to a new folder"), OnExportImages),
 
                 new ActionEntry ("EditMenuAction", null, Catalog.GetString ("_Edit"), null, null, null),
                 new ActionEntry ("SelectAllAction", Stock.SelectAll, null, "<control>A", null, OnSelectAll),
@@ -82,11 +81,9 @@ namespace PdfMod
                 new ToggleActionEntry ("ViewToolbar", null, Catalog.GetString ("Toolbar"), null, null, OnViewToolbar, true)
             );
 
-            // Not ready/finished yet
-            UpdateAction ("ExportImagesAction", false);
-
             this["RotateRightAction"].IconName = "object-rotate-right";
             this["RotateLeftAction"].IconName = "object-rotate-left";
+            this["ExportImagesAction"].IconName = "image-x-generic";
 
             // Don't show HelpAction unless we can at least access some of the GNOME api
             UpdateAction ("HelpAction", false);
@@ -300,8 +297,7 @@ namespace PdfMod
 
         private void OnExportImages (object o, EventArgs args)
         {
-            var pages = app.IconView.SelectedPages.ToList ();
-            var action = new ExportImagesAction (app.Document, pages);
+            var action = new ExportImagesAction (app.Document, app.Document.Pages);
             if (action.ExportableImageCount == 0) {
                 Log.Information ("Found zero exportable images in the selected pages");
                 return;
@@ -310,16 +306,21 @@ namespace PdfMod
             var export_path_base = Path.Combine (
                 Path.GetDirectoryName (app.Document.SuggestedSavePath),
                 // Translators: This is used for creating a folder name, be careful!
-                String.Format (Catalog.GetString ("{0} - Images for {1}"), app.Document.Title ?? app.Document.Filename, GetPageSummary (pages, 10))
+                //String.Format (Catalog.GetString ("{0} - Images for {1}"), app.Document.Title ?? app.Document.Filename, GetPageSummary (pages, 10))
+                app.Document.Title ?? System.IO.Path.GetFileNameWithoutExtension (app.Document.Filename)
             );
 
             var export_path = export_path_base;
             int i = 1;
-            while (Directory.Exists (export_path)) {
+            while (Directory.Exists (export_path) && i < 100) {
                 export_path = String.Format ("{0} ({1})", export_path_base, i++);
             }
 
-            Directory.CreateDirectory (export_path);
+            try {
+                Directory.CreateDirectory (export_path);
+            } catch (Exception e) {
+                Hyena.Log.Exception (e);
+            }
 
             action.Do (export_path);
             System.Diagnostics.Process.Start (export_path);
diff --git a/src/PdfMod/Resources/UIManager.xml b/src/PdfMod/Resources/UIManager.xml
index ebb8483..bd92105 100644
--- a/src/PdfMod/Resources/UIManager.xml
+++ b/src/PdfMod/Resources/UIManager.xml
@@ -6,6 +6,9 @@
       <menuitem action="SaveAsAction"/>
       <menuitem action="RecentMenuAction"/>
       <separator/>
+      <menuitem action="ExportImagesAction"/>
+      <menuitem action="InsertFromAction"/>
+      <separator/>
       <menuitem action="PropertiesAction"/>
       <separator/>
       <menuitem action="CloseAction"/>
@@ -15,9 +18,7 @@
       <menuitem action="RedoAction"/>
       <separator/>
       <menuitem action="ExtractAction"/>
-      <menuitem action="InsertFromAction"/>
       <menuitem action="RemoveAction"/>
-      <menuitem action="ExportImagesAction"/>
       <separator/>
       <menuitem action="RotateLeftAction"/>
       <menuitem action="RotateRightAction"/>
@@ -47,9 +48,10 @@
     <toolitem action="SaveAsAction"/>
     <separator/>
     <toolitem action="PropertiesAction"/>
+    <toolitem action="ExportImagesAction"/>
+    <toolitem action="InsertFromAction"/>
     <separator/>
     <toolitem action="ExtractAction"/>
-    <toolitem action="InsertFromAction"/>
     <toolitem action="RemoveAction"/>
     <toolitem action="RotateLeftAction"/>
     <toolitem action="RotateRightAction"/>
@@ -58,7 +60,6 @@
   <popup name="PageContextMenu" action="PageContextMenuAction">
     <menuitem action="ExtractAction"/>
     <menuitem action="RemoveAction"/>
-    <menuitem action="ExportImagesAction"/>
     <separator/>
     <menuitem action="RotateLeftAction"/>
     <menuitem action="RotateRightAction"/>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]