From: GiWoong Kim Date: Mon, 12 Jan 2015 05:23:11 +0000 (+0900) Subject: screenshot: support the transparent background for PNG X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.2~563 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b7e7a941d9f29ac58dd881573e98cdf8a992b494;p=sdk%2Femulator%2Fqemu.git screenshot: support the transparent background for PNG 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 --- 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 index 0000000000..ea00431f59 --- /dev/null +++ b/tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/ClipbrdTransfer.java @@ -0,0 +1,75 @@ +/** + * Clipboard + * + * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * GiWoong Kim + * SangHo Park + * + * 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; + } + } + } +} diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/ScreenShotDialog.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/ScreenShotDialog.java index 603017f80e..32a0aae345 100644 --- a/tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/ScreenShotDialog.java +++ b/tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/ScreenShotDialog.java @@ -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 { diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/SdlScreenShotWindow.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/SdlScreenShotWindow.java index f3cdef7917..8f1839ff90 100644 --- a/tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/SdlScreenShotWindow.java +++ b/tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/SdlScreenShotWindow.java @@ -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) { diff --git a/tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/ShmScreenShotWindow.java b/tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/ShmScreenShotWindow.java index 27fc590765..8841a7d5c5 100644 --- a/tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/ShmScreenShotWindow.java +++ b/tizen/src/skin/client/src/org/tizen/emulator/skin/screenshot/ShmScreenShotWindow.java @@ -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) {