screenshot: support the transparent background for PNG 57/35457/1
authorGiWoong Kim <giwoong.kim@samsung.com>
Mon, 12 Jan 2015 05:23:11 +0000 (14:23 +0900)
committerGiWoong Kim <giwoong.kim@samsung.com>
Mon, 16 Feb 2015 06:44:50 +0000 (15:44 +0900)
SWT library has problems to support the transparent background
for PNG image on Windows. So, we use an another way to support these.
1. Save - background was replaced by transparent pixel color as
alpha channel
2. Copy to Clipboard - use java.awt classes instead

Change-Id: I0ef908cfeda38f043643a4d837a6e7d2deff096f
Signed-off-by: GiWoong Kim <giwoong.kim@samsung.com>
tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/ClipbrdTransfer.java [new file with mode: 0644]
tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/ScreenShotDialog.java
tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/SdlScreenShotWindow.java
tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/ShmScreenShotWindow.java

diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/ClipbrdTransfer.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/ClipbrdTransfer.java
new file mode 100644 (file)
index 0000000..ea00431
--- /dev/null
@@ -0,0 +1,75 @@
+/**
+ * Clipboard
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * SangHo Park <sangho1206.park@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+package org.tizen.emulator.skin.screenshot;
+
+import java.awt.Image;
+import java.awt.Toolkit;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+
+import org.tizen.emulator.skin.util.StringUtil;
+
+public class ClipbrdTransfer {
+       public static void write(String filePath) {
+               if (StringUtil.isEmpty(filePath) == true) {
+                       return;
+               }
+
+               Toolkit toolkit = Toolkit.getDefaultToolkit();
+               toolkit.getSystemClipboard().setContents(
+                               new ClipbrdTransferable(toolkit.createImage(filePath)), null);
+       }
+
+       static class ClipbrdTransferable implements Transferable {
+               private Image image;
+
+               public ClipbrdTransferable(Image image) {
+                       this.image = image;
+               }
+
+               @Override
+               public DataFlavor[] getTransferDataFlavors() {
+                       return new DataFlavor[] { DataFlavor.imageFlavor };
+               }
+
+               @Override
+               public boolean isDataFlavorSupported(DataFlavor flavor) {
+                       return (flavor == DataFlavor.imageFlavor);
+               }
+
+               @Override
+               public Object getTransferData(DataFlavor flavor) {
+                       if (isDataFlavorSupported(flavor) == true) {
+                               return image;
+                       } else {
+                               return null;
+                       }
+               }
+       }
+}
index 603017f80e521b9c959b163d79c9eaf48c34fb32..32a0aae3450fa49c8096bfd4c9d36fed185927f8 100644 (file)
@@ -60,6 +60,7 @@ import org.eclipse.swt.graphics.ImageData;
 import org.eclipse.swt.graphics.ImageLoader;
 import org.eclipse.swt.graphics.PaletteData;
 import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
 import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
@@ -102,7 +103,7 @@ public class ScreenShotDialog {
 
        protected EmulatorSkin skin;
        protected EmulatorConfig config;
-       private Shell shell;
+       protected Shell shell;
 
        private ScrolledComposite scrollComposite;
        protected Canvas canvasShot;
@@ -354,7 +355,7 @@ public class ScreenShotDialog {
 
        private void clickShutter() throws ScreenShotException {
                Image maskImage = skin.getDisplayCanvas().getMaskImage();
-               if (maskImage != null) {
+               if (maskImage != null && skin.getDisplayCanvas().getRegion() != null) {
                        capture(SkinUtil.getMaskDataForImage(shell.getDisplay(), maskImage));
                } else {
                        capture(null);
@@ -526,7 +527,7 @@ public class ScreenShotDialog {
 
                                fileDialog.setOverwrite(true);
                                String filePath = fileDialog.open();
-                               saveFile(filePath, fileDialog);
+                               saveImageFile(filePath, fileDialog);
                        }
                });
 
@@ -559,65 +560,7 @@ public class ScreenShotDialog {
                                        }
                                });
 
-                               ImageLoader loader = new ImageLoader();
-                               ImageData shotData = imageShot.getImageData();
-
-                               if (SwtUtil.isWindowsPlatform()) {
-                                       /* convert to RGBA */
-                                       shotData.palette =
-                                                       new PaletteData(0xFF000000, 0x00FF0000, 0x0000FF00);
-                               }
-
-                               loader.data = new ImageData[] { shotData };
-
-                               if (SwtUtil.isLinuxPlatform() == true &&
-                                               SwtUtil.is64bitPlatform() == true) {
-                                       /* use Python for Ubuntu 64bit */
-                                       FileOutputStream fos = null;
-                                       String fileName = "screenshot" +
-                                                       skin.config.getArgInt(ArgsConstants.VM_BASE_PORT) + ".png";
-
-                                       try {
-                                               fos = new FileOutputStream(fileName, false);
-                                       } catch (FileNotFoundException ee) {
-                                               logger.log(Level.SEVERE, ee.getMessage(), ee);
-                                               SkinUtil.openMessage(shell, null,
-                                                               "Failed to copy to clipboard : \n" + ee.getMessage(),
-                                                               SWT.ICON_ERROR, config);
-                                               return;
-                                       }
-
-                                       loader.save(fos, SWT.IMAGE_PNG);
-                                       IOUtil.close(fos);
-
-                                       ProcessBuilder procPy = new ProcessBuilder();
-                                       procPy.command("python", "clipboard.py", fileName);
-
-                                       logger.info(procPy.command().toString());
-
-                                       try {
-                                               procPy.start();
-                                       } catch (Exception ee) {
-                                               logger.log(Level.SEVERE, ee.getMessage(), ee);
-                                               SkinUtil.openMessage(shell, null,
-                                                               "Failed to copy to clipboard : \n" + ee.getMessage(),
-                                                               SWT.ICON_ERROR, config);
-                                       }
-                               } else {
-                                       ByteArrayOutputStream bao = new ByteArrayOutputStream();
-                                       loader.save(bao, SWT.IMAGE_PNG);
-
-                                       ImageData pngData = new ImageData(
-                                                       new ByteArrayInputStream(bao.toByteArray()));
-
-                                       Object[] imageObject = new Object[] { pngData };
-
-                                       Transfer[] transfer = new Transfer[] { ImageTransfer.getInstance() };
-                                       Clipboard clipboard = new Clipboard(parent.getDisplay());
-                                       clipboard.setContents(imageObject, transfer);
-
-                                       clipboard.dispose();
-                               }
+                               copyImageToClipboard(imageShot);
                        }
                });
 
@@ -751,7 +694,90 @@ public class ScreenShotDialog {
                                ", y : " + skin.getEmulatorSkinState().getCurrentResolutionHeight() * (int)MAX_SCALE_MULTIPLE + " ");
        }
 
-       private void saveFile(String fileFullPath, FileDialog fileDialog) {
+       private void copyImageToClipboard(Image image) {
+               ImageData imageData = image.getImageData();
+
+               if (SwtUtil.isLinuxPlatform() == true &&
+                               SwtUtil.is64bitPlatform() == true) {
+                       /* use Python for Ubuntu 64bit */
+                       FileOutputStream fos = null;
+                       String fileName = "screenshot" +
+                                       skin.config.getArgInt(ArgsConstants.VM_BASE_PORT) + ".png";
+
+                       try {
+                               fos = new FileOutputStream(fileName, false);
+                       } catch (FileNotFoundException ee) {
+                               logger.log(Level.SEVERE, ee.getMessage(), ee);
+                               SkinUtil.openMessage(shell, null,
+                                               "Failed to copy to clipboard : \n" + ee.getMessage(),
+                                               SWT.ICON_ERROR, config);
+                               return;
+                       }
+
+                       ImageLoader loader = new ImageLoader();
+                       loader.data = new ImageData[] { imageData };
+
+                       loader.save(fos, SWT.IMAGE_PNG);
+                       IOUtil.close(fos);
+
+                       ProcessBuilder procPy = new ProcessBuilder();
+                       procPy.command("python", "clipboard.py", fileName);
+
+                       logger.info(procPy.command().toString());
+
+                       try {
+                               procPy.start();
+                       } catch (Exception ee) {
+                               logger.log(Level.SEVERE, ee.getMessage(), ee);
+                               SkinUtil.openMessage(shell, null,
+                                               "Failed to copy to clipboard : \n" + ee.getMessage(),
+                                               SWT.ICON_ERROR, config);
+                       }
+               } else if (SwtUtil.isWindowsPlatform() == true &&
+                               skin.getDisplayCanvas().getRegion() != null) {
+                       /* use java.awt to transfer a transparent background image */
+                       String fileName = "screenshot" +
+                                       skin.config.getArgInt(ArgsConstants.VM_BASE_PORT) + ".png";
+
+                       try {
+                               saveImageFileInternal(fileName, SWT.IMAGE_PNG, imageData);
+                       } catch (Exception ee) {
+                               logger.log(Level.SEVERE, ee.getMessage(), ee);
+                               SkinUtil.openMessage(shell, null,
+                                               "Failed to copy to clipboard : \n" + ee.getMessage(),
+                                               SWT.ICON_ERROR, config);
+                               return;
+                       }
+
+                       ClipbrdTransfer.write(fileName);
+               } else {
+                       /* use SWT */
+                       ImageLoader loader = new ImageLoader();
+
+                       if (SwtUtil.isWindowsPlatform() == true) {
+                               /* convert to RGBA */
+                               imageData.palette =
+                                               new PaletteData(0xFF000000, 0x00FF0000, 0x0000FF00);
+                       }
+                       loader.data = new ImageData[] { imageData };
+
+                       ByteArrayOutputStream bao = new ByteArrayOutputStream();
+                       loader.save(bao, SWT.IMAGE_PNG);
+
+                       ImageData pngData = new ImageData(
+                                       new ByteArrayInputStream(bao.toByteArray()));
+
+                       Object[] imageObject = new Object[] { pngData };
+
+                       Transfer[] transfer = new Transfer[] { ImageTransfer.getInstance() };
+                       Clipboard clipboard = new Clipboard(shell.getDisplay());
+                       clipboard.setContents(imageObject, transfer);
+
+                       clipboard.dispose();
+               }
+       }
+
+       private void saveImageFile(String fileFullPath, FileDialog fileDialog) {
                if (null == fileFullPath) {
                        return;
                }
@@ -768,12 +794,10 @@ public class ScreenShotDialog {
                                                "Use correct file name.", SWT.ICON_WARNING, config);
 
                                String path = fileDialog.open();
-                               saveFile(path, fileDialog);
+                               saveImageFile(path, fileDialog);
                        }
                }
 
-               FileOutputStream fos = null;
-
                try {
                        if (StringUtil.isEmpty(format)) {
                                if (fileFullPath.endsWith(".")) {
@@ -783,43 +807,60 @@ public class ScreenShotDialog {
                                }
                        }
 
-                       ImageLoader loader = new ImageLoader();
-                       loader.data = new ImageData[] { imageShot.getImageData() };
-
                        if (StringUtil.isEmpty(format) || format.equalsIgnoreCase("png")) {
-                               fos = new FileOutputStream(fileFullPath, false);
-                               loader.save(fos, SWT.IMAGE_PNG);
+                               saveImageFileInternal(fileFullPath,
+                                               SWT.IMAGE_PNG, imageShot.getImageData());
                        } else if (format.equalsIgnoreCase("jpg") || format.equalsIgnoreCase("jpeg")) {
-                               fos = new FileOutputStream(fileFullPath, false);
-                               loader.save(fos, SWT.IMAGE_JPEG);
+                               saveImageFileInternal(fileFullPath,
+                                               SWT.IMAGE_JPEG, imageShot.getImageData());
                        } else if (format.equalsIgnoreCase("bmp")) {
-                               fos = new FileOutputStream(fileFullPath, false);
-                               loader.save(fos, SWT.IMAGE_BMP);
+                               saveImageFileInternal(fileFullPath,
+                                               SWT.IMAGE_BMP, imageShot.getImageData());
                        } else {
                                SkinUtil.openMessage(shell, null,
                                                "Use the specified image formats. (PNG / JPG / JPEG / BMP)",
                                                SWT.ICON_WARNING, config);
 
                                String path = fileDialog.open();
-                               saveFile(path, fileDialog);
+                               saveImageFile(path, fileDialog);
                        }
-               } catch (FileNotFoundException ex) {
-                       logger.log(Level.WARNING, "Use correct file name.", ex);
-                       SkinUtil.openMessage(shell, null,
-                                       "Use correct file name.", SWT.ICON_WARNING, config);
-
-                       String path = fileDialog.open();
-                       saveFile(path, fileDialog);
                } catch (Exception ex) {
                        logger.log(Level.SEVERE, "Fail to save this image file.", ex);
                        SkinUtil.openMessage(shell, null,
                                        "Fail to save this image file.", SWT.ERROR, config);
 
                        String path = fileDialog.open();
-                       saveFile(path, fileDialog);
-               } finally {
-                       IOUtil.close(fos);
+                       saveImageFile(path, fileDialog);
+               }
+       }
+
+       private void saveImageFileInternal(String filePath,
+                       int imageFormat, ImageData imageData) throws Exception {
+               ImageLoader loader = new ImageLoader();
+
+               Image maskImage = skin.getDisplayCanvas().getMaskImage();
+               if (maskImage != null && skin.getDisplayCanvas().getRegion() != null &&
+                               SwtUtil.isWindowsPlatform() == true) {
+                       /* When save an PNG image with mask data on Windows,
+                        * transparent background cannot be applied to image file.
+                        * So, to handle alpha channel, transparent pixel field in ImageData class
+                        * should get a color key value from background area. */
+
+                       final int colorKey = imageData.palette.getPixel(new RGB(255, 0, 255));
+                       final int fakeKey = imageData.palette.getPixel(new RGB(255, 1, 255));
+                       SkinUtil.setColorKeyFromMask(shell.getDisplay(),
+                                       colorKey, fakeKey, maskImage.getImageData(), imageData);
+
+                       imageData.transparentPixel = colorKey;
+                       imageData.maskData = null;
                }
+
+               loader.data = new ImageData[] { imageData };
+
+               FileOutputStream fos = new FileOutputStream(filePath, false);
+               loader.save(fos, imageFormat);
+
+               IOUtil.close(fos);
        }
 
        public void open() throws ScreenShotException {
index f3cdef791766aaedc740b6f417cab4b3c5d90964..8f1839ff903a7c8fb0262e6ec5215d3b0b42d064 100644 (file)
@@ -33,7 +33,6 @@ import java.util.logging.Logger;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.ImageData;
 import org.eclipse.swt.graphics.PaletteData;
-import org.eclipse.swt.widgets.Display;
 import org.tizen.emulator.skin.EmulatorSdlSkin;
 import org.tizen.emulator.skin.comm.ICommunicator.SendCommand;
 import org.tizen.emulator.skin.comm.sock.SocketCommunicator.DataTranfer;
@@ -77,9 +76,9 @@ public class SdlScreenShotWindow extends ScreenShotDialog {
 
                        Image tempImage = imageShot;
                        if (maskData != null) {
-                               imageShot = new Image(Display.getDefault(), imageData, maskData);
+                               imageShot = new Image(shell.getDisplay(), imageData, maskData);
                        } else {
-                               imageShot = new Image(Display.getDefault(), imageData);
+                               imageShot = new Image(shell.getDisplay(), imageData);
                        }
 
                        if (tempImage != null) {
index 27fc590765c3bccfc7b6d45c790158433e57e832..8841a7d5c55c2427d1c6e93ad44a43b5a21724fd 100644 (file)
@@ -33,7 +33,6 @@ import java.util.logging.Logger;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.ImageData;
 import org.eclipse.swt.graphics.PaletteData;
-import org.eclipse.swt.widgets.Display;
 import org.tizen.emulator.skin.EmulatorShmSkin;
 import org.tizen.emulator.skin.config.EmulatorConfig;
 import org.tizen.emulator.skin.exception.ScreenShotException;
@@ -78,9 +77,9 @@ public class ShmScreenShotWindow extends ScreenShotDialog {
 
                Image tempImage = imageShot;
                if (maskData != null) {
-                       imageShot = new Image(Display.getDefault(), imageData, maskData);
+                       imageShot = new Image(shell.getDisplay(), imageData, maskData);
                } else {
-                       imageShot = new Image(Display.getDefault(), imageData);
+                       imageShot = new Image(shell.getDisplay(), imageData);
                }
 
                if (tempImage != null) {