Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025 026package javafx.embed.swing; 027 028import java.awt.AlphaComposite; 029import java.awt.Graphics2D; 030import java.awt.image.BufferedImage; 031import java.nio.IntBuffer; 032import javafx.scene.image.Image; 033import javafx.scene.image.PixelFormat; 034import javafx.scene.image.PixelReader; 035import javafx.scene.image.PixelWriter; 036import javafx.scene.image.WritableImage; 037import javafx.scene.image.WritablePixelFormat; 038import sun.awt.image.IntegerComponentRaster; 039 040/** 041 * This class provides utility methods for converting data types between 042 * Swing/AWT and JavaFX formats. 043 */ 044public class SwingFXUtils { 045 private SwingFXUtils() {} // no instances 046 047 /** 048 * Snapshots the specified {@link BufferedImage} and stores a copy of 049 * its pixels into a JavaFX {@link Image} object, creating a new 050 * object if needed. 051 * The returned {@code Image} will be a static snapshot of the state 052 * of the pixels in the {@code BufferedImage} at the time the method 053 * completes. Further changes to the {@code BufferedImage} will not 054 * be reflected in the {@code Image}. 055 * <p> 056 * The optional JavaFX {@link WritableImage} parameter may be reused 057 * to store the copy of the pixels. 058 * A new {@code Image} will be created if the supplied object is null, 059 * is too small or of a type which the image pixels cannot be easily 060 * converted into. 061 * 062 * @param bimg the {@code BufferedImage} object to be converted 063 * @param wimg an optional {@code WritableImage} object that can be 064 * used to store the returned pixel data 065 * @return an {@code Image} object representing a snapshot of the 066 * current pixels in the {@code BufferedImage}. 067 * @since 2.2 068 */ 069 public static WritableImage toFXImage(BufferedImage bimg, WritableImage wimg) { 070 int bw = bimg.getWidth(); 071 int bh = bimg.getHeight(); 072 switch (bimg.getType()) { 073 case BufferedImage.TYPE_INT_ARGB: 074 case BufferedImage.TYPE_INT_ARGB_PRE: 075 break; 076 default: 077 BufferedImage converted = 078 new BufferedImage(bw, bh, BufferedImage.TYPE_INT_ARGB_PRE); 079 Graphics2D g2d = converted.createGraphics(); 080 g2d.drawImage(bimg, 0, 0, null); 081 g2d.dispose(); 082 bimg = converted; 083 break; 084 } 085 // assert(bimg.getType == TYPE_INT_ARGB[_PRE]); 086 if (wimg != null) { 087 int iw = (int) wimg.getWidth(); 088 int ih = (int) wimg.getHeight(); 089 if (iw < bw || ih < bh) { 090 wimg = null; 091 } else if (bw < iw || bh < ih) { 092 int empty[] = new int[iw]; 093 PixelWriter pw = wimg.getPixelWriter(); 094 PixelFormat pf = PixelFormat.getIntArgbPreInstance(); 095 if (bw < iw) { 096 pw.setPixels(bw, 0, iw-bw, bh, pf, empty, 0, 0); 097 } 098 if (bh < ih) { 099 pw.setPixels(0, bh, iw, ih-bh, pf, empty, 0, 0); 100 } 101 } 102 } 103 if (wimg == null) { 104 wimg = new WritableImage(bw, bh); 105 } 106 PixelWriter pw = wimg.getPixelWriter(); 107 IntegerComponentRaster icr = (IntegerComponentRaster) bimg.getRaster(); 108 int data[] = icr.getDataStorage(); 109 int offset = icr.getDataOffset(0); 110 int scan = icr.getScanlineStride(); 111 PixelFormat<IntBuffer> pf = (bimg.isAlphaPremultiplied() ? 112 PixelFormat.getIntArgbPreInstance() : 113 PixelFormat.getIntArgbInstance()); 114 pw.setPixels(0, 0, bw, bh, pf, data, offset, scan); 115 return wimg; 116 } 117 118 /** 119 * Snapshots the specified JavaFX {@link Image} object and stores a 120 * copy of its pixels into a {@link BufferedImage} object, creating 121 * a new object if needed. 122 * The method will only convert a JavaFX {@code Image} that is readable 123 * as per the conditions on the 124 * {@link Image#getPixelReader() Image.getPixelReader()} 125 * method. 126 * If the {@code Image} is not readable, as determined by its 127 * {@code getPixelReader()} method, then this method will return null. 128 * If the {@code Image} is a writable, or other dynamic image, then 129 * the {@code BufferedImage} will only be set to the current state of 130 * the pixels in the image as determined by its {@link PixelReader}. 131 * Further changes to the pixels of the {@code Image} will not be 132 * reflected in the returned {@code BufferedImage}. 133 * <p> 134 * The optional {@code BufferedImage} parameter may be reused to store 135 * the copy of the pixels. 136 * A new {@code BufferedImage} will be created if the supplied object 137 * is null, is too small or of a type which the image pixels cannot 138 * be easily converted into. 139 * 140 * @param img the JavaFX {@code Image} to be converted 141 * @param bimg an optional {@code BufferedImage} object that may be 142 * used to store the returned pixel data 143 * @return a {@code BufferedImage} containing a snapshot of the JavaFX 144 * {@code Image}, or null if the {@code Image} is not readable. 145 * @since 2.2 146 */ 147 public static BufferedImage fromFXImage(Image img, BufferedImage bimg) { 148 PixelReader pr = img.getPixelReader(); 149 if (pr == null) { 150 return null; 151 } 152 int iw = (int) img.getWidth(); 153 int ih = (int) img.getHeight(); 154 if (bimg != null) { 155 int type = bimg.getType(); 156 int bw = bimg.getWidth(); 157 int bh = bimg.getHeight(); 158 if (bw < iw || bh < ih || 159 (type != BufferedImage.TYPE_INT_ARGB && 160 type != BufferedImage.TYPE_INT_ARGB_PRE)) 161 { 162 bimg = null; 163 } else if (iw < bw || ih < bh) { 164 Graphics2D g2d = bimg.createGraphics(); 165 g2d.setComposite(AlphaComposite.Clear); 166 g2d.fillRect(0, 0, bw, bh); 167 g2d.dispose(); 168 } 169 } 170 if (bimg == null) { 171 bimg = new BufferedImage(iw, ih, BufferedImage.TYPE_INT_ARGB_PRE); 172 } 173 IntegerComponentRaster icr = (IntegerComponentRaster) bimg.getRaster(); 174 int offset = icr.getDataOffset(0); 175 int scan = icr.getScanlineStride(); 176 int data[] = icr.getDataStorage(); 177 WritablePixelFormat<IntBuffer> pf = (bimg.isAlphaPremultiplied() ? 178 PixelFormat.getIntArgbPreInstance() : 179 PixelFormat.getIntArgbInstance()); 180 pr.getPixels(0, 0, iw, ih, pf, data, offset, scan); 181 return bimg; 182 } 183}