Author: tilman
Date: Fri Mar 21 17:40:54 2014
New Revision: 1579990

URL: http://svn.apache.org/r1579990
Log:
PDFBOX-1990: added writing bitonal and grayscale images as single color samples 
and improved the unit test

Modified:
    
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactory.java
    
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactoryTest.java
    
pdfbox/trunk/pdfbox/src/test/resources/org/apache/pdfbox/pdmodel/graphics/image/png.png

Modified: 
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactory.java
URL: 
http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactory.java?rev=1579990&r1=1579989&r2=1579990&view=diff
==============================================================================
--- 
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactory.java
 (original)
+++ 
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactory.java
 Fri Mar 21 17:40:54 2014
@@ -21,11 +21,13 @@ import java.awt.image.WritableRaster;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import javax.imageio.stream.MemoryCacheImageOutputStream;
 import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.cos.COSName;
 import org.apache.pdfbox.filter.Filter;
 import org.apache.pdfbox.filter.FilterFactory;
 import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceColorSpace;
 import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceGray;
 import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB;
 import static 
org.apache.pdfbox.pdmodel.graphics.image.ImageFactory.getColorImage;
@@ -48,22 +50,54 @@ public class LosslessFactory
     public static PDImageXObject createFromImage(PDDocument document, 
BufferedImage image)
             throws IOException
     {
+        int bpc;
+        PDDeviceColorSpace deviceColorSpace;
+
         // extract color channel
         BufferedImage awtColorImage = getColorImage(image);
 
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
 
-        //TODO use bit writing, indexed, etc
-        int h = awtColorImage.getHeight();
-        int w = awtColorImage.getWidth();
-        for (int y = 0; y < h; ++y)
+        //TODO: using the grayscale branch for BufferedImage.TYPE_BYTE_GRAY
+        // fails the test. We use the RGB branch instead until this is fixed.
+        if ((//image.getType() == BufferedImage.TYPE_BYTE_GRAY || 
+                image.getType() == BufferedImage.TYPE_BYTE_BINARY)
+                && image.getColorModel().getPixelSize() <= 8)
+        {
+            MemoryCacheImageOutputStream mcios = new 
MemoryCacheImageOutputStream(bos);
+
+            // grayscale images need one color per sample
+            bpc = image.getColorModel().getPixelSize();
+            deviceColorSpace = PDDeviceGray.INSTANCE;
+            int h = awtColorImage.getHeight();
+            int w = awtColorImage.getWidth();
+            for (int y = 0; y < h; ++y)
+            {
+                for (int x = 0; x < w; ++x)
+                {
+                    mcios.writeBits(awtColorImage.getRGB(x, y), bpc);
+                }
+            }
+            mcios.writeBits(0, 7); // padding
+            mcios.flush();
+            mcios.close();
+        }
+        else
         {
-            for (int x = 0; x < w; ++x)
+            // RGB
+            bpc = 8;
+            deviceColorSpace = PDDeviceRGB.INSTANCE;
+            int h = awtColorImage.getHeight();
+            int w = awtColorImage.getWidth();
+            for (int y = 0; y < h; ++y)
             {
-                Color color = new Color(awtColorImage.getRGB(x, y));
-                bos.write(color.getRed());
-                bos.write(color.getGreen());
-                bos.write(color.getBlue());
+                for (int x = 0; x < w; ++x)
+                {
+                    Color color = new Color(awtColorImage.getRGB(x, y));
+                    bos.write(color.getRed());
+                    bos.write(color.getGreen());
+                    bos.write(color.getBlue());
+                }
             }
         }
 
@@ -79,8 +113,8 @@ public class LosslessFactory
         COSDictionary dict = pdImage.getCOSStream();
         dict.setItem(COSName.FILTER, COSName.FLATE_DECODE);
 
-        pdImage.setColorSpace(PDDeviceRGB.INSTANCE); //TODO from awtColorImage
-        pdImage.setBitsPerComponent(8); //TODO other sizes
+        pdImage.setColorSpace(deviceColorSpace);
+        pdImage.setBitsPerComponent(bpc);
         pdImage.setHeight(awtColorImage.getHeight());
         pdImage.setWidth(awtColorImage.getWidth());
 

Modified: 
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactoryTest.java
URL: 
http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactoryTest.java?rev=1579990&r1=1579989&r2=1579990&view=diff
==============================================================================
--- 
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactoryTest.java
 (original)
+++ 
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactoryTest.java
 Fri Mar 21 17:40:54 2014
@@ -40,9 +40,31 @@ public class LosslessFactoryTest extends
     {
         PDDocument document = new PDDocument();
         BufferedImage image = 
ImageIO.read(this.getClass().getResourceAsStream("png.png"));
+
         PDImageXObject ximage = LosslessFactory.createFromImage(document, 
image);
         validate(ximage, 8, 344, 287, "png");
+        checkIdent(image, ximage.getImage());
+
+        // Create a grayscale image
+        BufferedImage grayImage = new BufferedImage(image.getWidth(), 
image.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
+        Graphics g = grayImage.getGraphics();
+        g.drawImage(image, 0, 0, null);
+        g.dispose();
+        ximage = LosslessFactory.createFromImage(document, grayImage);
+        validate(ximage, 8, 344, 287, "png");
+        checkIdent(grayImage, ximage.getImage());
+
+        // Create a bitonal image
+        BufferedImage bitonalImage = new BufferedImage(image.getWidth(), 
image.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
+        g = bitonalImage.getGraphics();
+        g.drawImage(image, 0, 0, null);
+        g.dispose();
+        ximage = LosslessFactory.createFromImage(document, bitonalImage);
+        validate(ximage, 1, 344, 287, "png");
+        checkIdent(bitonalImage, ximage.getImage());
+
         document.close();
+
     }
 
     /**
@@ -82,4 +104,29 @@ public class LosslessFactoryTest extends
         document.close();
     }
 
+    /**
+     * Check whether images are identical.
+     *
+     * @param expectedImage
+     * @param actualImage
+     */
+    private void checkIdent(BufferedImage expectedImage, BufferedImage 
actualImage)
+    {
+        String errMsg = "";
+
+        int w = expectedImage.getWidth();
+        int h = expectedImage.getHeight();
+        for (int y = 0; y < h; ++y)
+        {
+            for (int x = 0; x < w; ++x)
+            {
+                if (expectedImage.getRGB(x, y) != actualImage.getRGB(x, y))
+                {
+                    errMsg = String.format("(%d,%d) %X != %X", x, y, 
expectedImage.getRGB(x, y), actualImage.getRGB(x, y));
+                }
+                assertEquals(errMsg, expectedImage.getRGB(x, y), 
actualImage.getRGB(x, y));
+            }
+        }
+    }
+
 }

Modified: 
pdfbox/trunk/pdfbox/src/test/resources/org/apache/pdfbox/pdmodel/graphics/image/png.png
URL: 
http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/resources/org/apache/pdfbox/pdmodel/graphics/image/png.png?rev=1579990&r1=1579989&r2=1579990&view=diff
==============================================================================
Binary files - no diff available.


Reply via email to