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.scene.image; 027 028import com.sun.javafx.tk.ImageLoader; 029import com.sun.javafx.tk.PlatformImage; 030import com.sun.javafx.tk.Toolkit; 031import java.nio.Buffer; 032import java.nio.ByteBuffer; 033import java.nio.IntBuffer; 034import javafx.beans.property.ReadOnlyObjectProperty; 035import javafx.scene.paint.Color; 036 037/** 038 * The {@code WritableImage} class represents a custom graphical image 039 * that is constructed from pixels supplied by the application, and possibly 040 * from {@code PixelReader} objects from any number of sources, including 041 * images read from a file or URL. 042 * @since 2.2 043 */ 044public class WritableImage extends Image { 045 046 static { 047 Toolkit.setWritableImageAccessor(new Toolkit.WritableImageAccessor() { 048 @Override public void loadTkImage(WritableImage wimg, Object loader) { 049 wimg.loadTkImage(loader); 050 } 051 052 @Override public Object getTkImageLoader(WritableImage wimg) { 053 return wimg.getTkImageLoader(); 054 } 055 }); 056 } 057 058 private ImageLoader tkImageLoader; 059 060 /** 061 * Construct an empty image of the specified dimensions. 062 * The image will initially be filled with transparent pixels. 063 * Images constructed this way will always be readable and writable 064 * so the corresponding getPixelReader() and getPixelWriter() will 065 * always return valid objects. 066 * The dimensions must both be positive numbers <code>(> 0)</code>. 067 * 068 * @param width the desired width of the writable image 069 * @param height the desired height of the desired image 070 * @throws IllegalArgumentException if either dimension is negative or zero. 071 */ 072 public WritableImage(int width, int height) { 073 super(width, height); 074 } 075 076 /** 077 * Construct an image of the specified dimensions, initialized from 078 * the indicated {@link PixelReader}. 079 * The image will initially be filled with data returned from the 080 * {@code PixelReader}. 081 * If the {@code PixelReader} accesses a surface that does not contain 082 * the necessary number of pixel rows and columns then an 083 * {@link ArrayIndexOutOfBoundsException} will be thrown. 084 * Images constructed this way will always be readable and writable 085 * so the corresponding getPixelReader() and getPixelWriter() will 086 * always return valid objects. 087 * The dimensions must both be positive numbers <code>(> 0)</code>. 088 * 089 * @param width the desired width of the writable image and the 090 * width of the region to be read from the {@code reader} 091 * @param height the desired height of the desired image and the 092 * width of the region to be read from the {@code reader} 093 * @throws ArrayIndexOutOfBoundsException if the {@code reader} does 094 * not access a surface of at least the requested dimensions 095 * @throws IllegalArgumentException if either dimension is negative or zero. 096 */ 097 public WritableImage(PixelReader reader, int width, int height) { 098 super(width, height); 099 getPixelWriter().setPixels(0, 0, width, height, reader, 0, 0); 100 } 101 102 /** 103 * Construct an image of the specified dimensions, initialized from 104 * the indicated region of the {@link PixelReader}. 105 * The image will initially be filled with data returned from the 106 * {@code PixelReader} for the specified region. 107 * If the {@code PixelReader} accesses a surface that does not contain 108 * the necessary number of pixel rows and columns then an 109 * {@link ArrayIndexOutOfBoundsException} will be thrown. 110 * Images constructed this way will always be readable and writable 111 * so the corresponding getPixelReader() and getPixelWriter() will 112 * always return valid objects. 113 * The dimensions must both be positive numbers <code>(> 0)</code>. 114 * 115 * @param x the X coordinate of the upper left corner of the region to 116 * read from the {@code reader} 117 * @param y the Y coordinate of the upper left corner of the region to 118 * read from the {@code reader} 119 * @param width the desired width of the writable image and the 120 * width of the region to be read from the {@code reader} 121 * @param height the desired height of the desired image and the 122 * width of the region to be read from the {@code reader} 123 * @throws ArrayIndexOutOfBoundsException if the {@code reader} does 124 * not access a surface containing at least the indicated region 125 * @throws IllegalArgumentException if either dimension is negative or zero. 126 */ 127 public WritableImage(PixelReader reader, 128 int x, int y, int width, int height) 129 { 130 super(width, height); 131 getPixelWriter().setPixels(0, 0, width, height, reader, x, y); 132 } 133 134 @Override 135 boolean isAnimation() { 136 return true; 137 } 138 139 @Override 140 boolean pixelsReadable() { 141 return true; 142 } 143 144 private PixelWriter writer; 145 /** 146 * This method returns a {@code PixelWriter} that provides access to 147 * write the pixels of the image. 148 * 149 * @return the {@code PixelWriter} for writing pixels to the image 150 */ 151 public final PixelWriter getPixelWriter() { 152 if (getProgress() < 1.0 || isError()) { 153 return null; 154 } 155 if (writer == null) { 156 writer = new PixelWriter() { 157 ReadOnlyObjectProperty<PlatformImage> pimgprop = 158 acc_platformImageProperty(); 159 160 @Override 161 public PixelFormat getPixelFormat() { 162 PlatformImage pimg = getWritablePlatformImage(); 163 return pimg.getPlatformPixelFormat(); 164 } 165 166 @Override 167 public void setArgb(int x, int y, int argb) { 168 getWritablePlatformImage().setArgb(x, y, argb); 169 pixelsDirty(); 170 } 171 172 @Override 173 public void setColor(int x, int y, Color c) { 174 int a = (int) Math.round(c.getOpacity() * 255); 175 int r = (int) Math.round(c.getRed() * 255); 176 int g = (int) Math.round(c.getGreen() * 255); 177 int b = (int) Math.round(c.getBlue() * 255); 178 setArgb(x, y, (a << 24) | (r << 16) | (g << 8) | b); 179 } 180 181 @Override 182 public <T extends Buffer> 183 void setPixels(int x, int y, int w, int h, 184 PixelFormat<T> pixelformat, 185 T buffer, int scanlineStride) 186 { 187 PlatformImage pimg = getWritablePlatformImage(); 188 pimg.setPixels(x, y, w, h, pixelformat, 189 buffer, scanlineStride); 190 pixelsDirty(); 191 } 192 193 @Override 194 public void setPixels(int x, int y, int w, int h, 195 PixelFormat<ByteBuffer> pixelformat, 196 byte buffer[], int offset, int scanlineStride) 197 { 198 PlatformImage pimg = getWritablePlatformImage(); 199 pimg.setPixels(x, y, w, h, pixelformat, 200 buffer, offset, scanlineStride); 201 pixelsDirty(); 202 } 203 204 @Override 205 public void setPixels(int x, int y, int w, int h, 206 PixelFormat<IntBuffer> pixelformat, 207 int buffer[], int offset, int scanlineStride) 208 { 209 PlatformImage pimg = getWritablePlatformImage(); 210 pimg.setPixels(x, y, w, h, pixelformat, 211 buffer, offset, scanlineStride); 212 pixelsDirty(); 213 } 214 215 @Override 216 public void setPixels(int writex, int writey, int w, int h, 217 PixelReader reader, int readx, int ready) 218 { 219 PlatformImage pimg = getWritablePlatformImage(); 220 pimg.setPixels(writex, writey, w, h, reader, readx, ready); 221 pixelsDirty(); 222 } 223 }; 224 } 225 return writer; 226 } 227 228 private void loadTkImage(Object loader) { 229 if (!(loader instanceof ImageLoader)) { 230 throw new IllegalArgumentException("Unrecognized image loader: " 231 + loader); 232 } 233 ImageLoader tkLoader = (ImageLoader)loader; 234 if (tkLoader.getWidth() != (int)this.getWidth() 235 || tkLoader.getHeight() != (int)this.getHeight()) 236 { 237 throw new IllegalArgumentException("Size of loader does not match size of image"); 238 } 239 240 super.setPlatformImage(tkLoader.getFrame(0)); 241 this.tkImageLoader = tkLoader; 242 } 243 244 private Object getTkImageLoader() { 245 return tkImageLoader; 246 } 247}