001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.mobility.svgcore.export;
042:
043: import java.awt.Color;
044: import java.awt.Dimension;
045: import java.awt.Graphics;
046: import java.awt.image.BufferedImage;
047: import java.awt.image.IndexColorModel;
048: import java.awt.image.WritableRaster;
049: import java.io.ByteArrayInputStream;
050: import java.io.ByteArrayOutputStream;
051: import java.io.IOException;
052: import java.io.InputStream;
053: import java.io.OutputStream;
054: import java.util.Collection;
055: import java.util.Iterator;
056: import java.util.MissingResourceException;
057: import javax.imageio.IIOImage;
058: import javax.imageio.ImageIO;
059: import javax.imageio.ImageReader;
060: import javax.imageio.ImageWriteParam;
061: import javax.imageio.ImageWriter;
062: import javax.imageio.stream.ImageInputStream;
063: import javax.imageio.stream.ImageOutputStream;
064: import javax.microedition.m2g.SVGImage;
065: import javax.microedition.m2g.ScalableGraphics;
066: import javax.swing.text.BadLocationException;
067: import org.netbeans.api.progress.ProgressHandle;
068: import org.netbeans.api.progress.ProgressHandleFactory;
069: import org.netbeans.api.project.FileOwnerQuery;
070: import org.netbeans.api.project.Project;
071: import org.netbeans.modules.mobility.project.J2MEProject;
072: import org.netbeans.modules.mobility.project.ProjectConfigurationsHelper;
073: import org.netbeans.modules.mobility.svgcore.SVGDataObject;
074: import org.netbeans.modules.mobility.svgcore.composer.SceneManager;
075: import org.netbeans.spi.project.ProjectConfiguration;
076: import org.netbeans.spi.project.support.ant.AntProjectHelper;
077: import org.netbeans.spi.project.support.ant.EditableProperties;
078: import org.openide.filesystems.FileObject;
079: import org.openide.util.NbBundle;
080: import org.w3c.dom.svg.SVGSVGElement;
081:
082: /**
083: * Helper for rasterizing SVG images/animations into bitmap images
084: *
085: * @author breh
086: */
087: public class AnimationRasterizer {
088: private static final int PATTERN_SIZE = 10;
089: private static final Color PATTERN_COLOR1 = new Color(192, 192, 192);
090: private static final Color PATTERN_COLOR2 = new Color(220, 220, 220);
091: private static final Color BACKGROUND_COLOR = Color.WHITE;
092:
093: public enum CompressionLevel {
094: MAXIMUM(getMessage("LBL_CompressionMaximum"), 10), //NOI18N
095: VERY_HIGH(getMessage("LBL_CompressionVeryHigh"), 30), //NOI18N
096: HIGH(getMessage("LBL_CompressionHigh"), 40), //NOI18N
097: MEDIUM(getMessage("LBL_CompressionMedium"), 60), //NOI18N
098: LOW(getMessage("LBL_CompressionLow"), 80), //NOI18N
099: MINIMUM(getMessage("LBL_CompressionMinimum"), 99); //NOI18N
100:
101: private final String m_name;
102: private final int m_rate;
103:
104: CompressionLevel(String name, int rate) {
105: m_name = name;
106: m_rate = rate;
107: }
108:
109: public String toString() {
110: return m_name;
111: }
112:
113: public int getRate() {
114: return m_rate;
115: }
116:
117: public static CompressionLevel getLevel(int rate) {
118: assert rate >= 0 && rate <= 99;
119: for (CompressionLevel level : CompressionLevel.values()) {
120: if (rate <= level.getRate()) {
121: return level;
122: }
123: }
124: assert false : "Could not find compression level for rate: "
125: + rate; //NOI18N
126: return MINIMUM;
127: }
128: }
129:
130: private interface ColorReducer {
131: BufferedImage reduceColors(BufferedImage image, Params params);
132: }
133:
134: public enum ColorReductionMethod implements ColorReducer {
135: QUANTIZE(getMessage("LBL_ColorReductionColorQuantization")) { //NOI18N
136: public BufferedImage reduceColors(BufferedImage image,
137: Params params) {
138: return reduceColorsQuantize(image, params);
139: }
140: },
141: MEDIAN_CUT(getMessage("LBL_ColorReductionMedianCut")) { //NOI18N
142: public BufferedImage reduceColors(BufferedImage image,
143: Params params) {
144: return reduceColorsMedianCut(image, params);
145: }
146: };
147:
148: private final String m_displayName;
149:
150: ColorReductionMethod(String displayName) {
151: m_displayName = displayName;
152: }
153:
154: public String toString() {
155: return m_displayName;
156: }
157: }
158:
159: public enum ImageType {
160: JPEG("JPG", "JPEG", true, false, false, ".jpg"), //NOI18N
161: PNG8("PNG", "PNG-8", false, true, true, ".png"), //NOI18N
162: PNG24("PNG", "PNG-24", false, true, false, ".png"); //NOI18N
163:
164: private final String m_name;
165: private final String m_displayName;
166: private final boolean m_supportsCompression;
167: private final boolean m_supportsTransparency;
168: private final String m_extension;
169: private final boolean m_colorReduction;
170:
171: ImageType(String name, String displayName,
172: boolean supportsCompression,
173: boolean supportsTransparency, boolean colorReduction,
174: String extension) {
175: m_name = name;
176: m_displayName = displayName;
177: m_supportsCompression = supportsCompression;
178: m_supportsTransparency = supportsTransparency;
179: m_colorReduction = colorReduction;
180: m_extension = extension;
181: }
182:
183: public boolean supportsCompression() {
184: return m_supportsCompression;
185: }
186:
187: public boolean supportsTransparency() {
188: return m_supportsTransparency;
189: }
190:
191: public boolean needsColorReduction() {
192: return m_colorReduction;
193: }
194:
195: public String getName() {
196: return m_name;
197: }
198:
199: public String toString() {
200: return m_displayName;
201: }
202:
203: public String getFileName(String filename) {
204: String str = filename.toLowerCase();
205: String ext = "." + SVGDataObject.EXT_SVG; //NOI18N
206: if (!str.endsWith(ext)) {
207: ext = "." + SVGDataObject.EXT_SVGZ; //NOI18N
208: if (!str.endsWith(ext)) {
209: ext = ""; //NOI18N
210: }
211: }
212: filename = filename.substring(0, filename.length()
213: - ext.length())
214: + m_extension;
215: return filename;
216: }
217: }
218:
219: public static interface Params {
220: SVGImage getSVGImage() throws IOException, BadLocationException;
221:
222: int getImageWidth();
223:
224: int getImageHeight();
225:
226: float getStartTime();
227:
228: float getEndTime();
229:
230: float getFramesPerSecond();
231:
232: boolean isForAllConfigurations();
233:
234: double getRatio();
235:
236: float getCompressionQuality();
237:
238: boolean isProgressive();
239:
240: boolean isInSingleImage();
241:
242: boolean isTransparent();
243:
244: AnimationRasterizer.ImageType getImageType();
245:
246: void setImageWidth(int w);
247:
248: void setImageHeight(int h);
249:
250: int getNumberFrames();
251:
252: J2MEProject getProject();
253:
254: String getElementId();
255:
256: ColorReductionMethod getColorReductionMethod();
257: }
258:
259: public static class PreviewInfo {
260: final BufferedImage m_image;
261: final String m_imageFormat;
262: final int m_imageSize;
263:
264: private PreviewInfo(BufferedImage image, String format, int size) {
265: m_image = image;
266: m_imageFormat = format;
267: m_imageSize = size;
268: }
269: }
270:
271: public static String createFileNameRoot(SVGDataObject dObj,
272: Params params, ProjectConfiguration projectCfg,
273: boolean fullPath) {
274: FileObject fo = dObj.getPrimaryFile();
275: String filenameRoot;
276:
277: if (fullPath) {
278: filenameRoot = fo.getPath();
279: String ext = fo.getExt();
280: //remove the extension including the dot
281: if (ext != null && ext.length() > 0) {
282: filenameRoot = filenameRoot.substring(0, filenameRoot
283: .length()
284: - ext.length() - 1);
285: }
286: } else {
287: filenameRoot = fo.getName();
288: }
289:
290: if (params.isForAllConfigurations()) {
291: if (projectCfg != null) {
292: if (projectCfg != params.getProject()
293: .getConfigurationHelper()
294: .getDefaultConfiguration()) {
295: filenameRoot += "_" + projectCfg.getDisplayName(); //NOI18N
296: }
297: } else {
298: filenameRoot += "_{configuration-name-here}"; //NOI18N
299: }
300: } else {
301: filenameRoot += getActiveConfigurationName(fo);
302: }
303:
304: if (params.getElementId() != null) {
305: filenameRoot += "_" + params.getElementId(); //NOI18N
306: }
307:
308: return filenameRoot;
309: }
310:
311: public static String createFileName(String filenameRoot,
312: Params params, int frameIndex, int frameNum) {
313: if (!params.isInSingleImage()) {
314: assert frameIndex >= 0;
315: assert frameNum >= 0;
316: filenameRoot += "_" + frameIndex + "_" + frameNum; //NOI18N
317: }
318: filenameRoot = params.getImageType().getFileName(filenameRoot);
319: return filenameRoot;
320: }
321:
322: public static void export(final SVGDataObject dObj,
323: final Params params) throws MissingResourceException {
324: FileObject fo = dObj.getPrimaryFile();
325: export(dObj, params, fo.getParent());
326: }
327:
328: public static FileObject export(final SVGDataObject dObj,
329: final Params params, final FileObject directory)
330: throws MissingResourceException {
331: final ProgressHandle handle = ProgressHandleFactory
332: .createHandle(getMessage("TITLE_AnimationExportProgress")); //NOI18N
333: FileObject file = null;
334: try {
335: if (!params.isForAllConfigurations()) {
336: handle.start(1);
337:
338: String filenameRoot = createFileNameRoot(dObj, params,
339: null, false);
340: file = rasterizeImage(params.getSVGImage(), directory,
341: filenameRoot, params);
342: handle.progress(1);
343: } else {
344: FileObject fo = dObj.getPrimaryFile();
345: Collection<ProjectConfiguration> configurations = params
346: .getProject().getConfigurationHelper()
347: .getConfigurations();
348: handle.start(configurations.size());
349:
350: int stepsDone = 0;
351:
352: int imageWidth = params.getImageWidth();
353: int imageHeigth = params.getImageHeight();
354: for (ProjectConfiguration configuration : configurations) {
355: Dimension activeDimenson = ScreenSizeHelper
356: .getCurrentDeviceScreenSize(fo, null);
357: double ratioWidth = (double) imageWidth
358: / activeDimenson.getWidth();
359: double ratioHeight = (double) imageHeigth
360: / activeDimenson.getHeight();
361: assert configuration != null;
362: String filenameRoot = createFileNameRoot(dObj,
363: params, configuration, false);
364: Dimension dim = ScreenSizeHelper
365: .getCurrentDeviceScreenSize(fo,
366: configuration.getDisplayName());
367:
368: params
369: .setImageWidth((int) (dim.getWidth() * ratioWidth));
370: params
371: .setImageHeight((int) (dim.getHeight() * ratioHeight));
372:
373: rasterizeImage(params.getSVGImage(), directory,
374: filenameRoot, params);
375: handle.progress(++stepsDone);
376: }
377: }
378: directory.refresh(false);
379: } catch (Exception ex) {
380: SceneManager.error("Image export failed.", ex); //NOI18N
381: } finally {
382: handle.finish();
383: }
384: return file;
385: }
386:
387: private static BufferedImage adjustImage(BufferedImage img,
388: Params params) {
389: if (params.getImageType().needsColorReduction()) {
390: img = params.getColorReductionMethod().reduceColors(img,
391: params);
392: }
393: return img;
394: }
395:
396: public static PreviewInfo previewFrame(SVGImage svgImage,
397: Params params, int frameIndex, float time)
398: throws IOException {
399: BufferedImage img;
400:
401: if (frameIndex != -1
402: && ImageType.PNG8.equals(params.getImageType())
403: && params.isInSingleImage()) {
404: img = rasterizeFramesInSingleImage(svgImage, params);
405: int w = params.getImageWidth();
406: int h = params.getImageHeight();
407: BufferedImage temp = createBuffer(w, h, params
408: .isTransparent());
409: Graphics g = temp.createGraphics();
410: int x = frameIndex * w;
411: g.drawImage(img, 0, 0, w - 1, h - 1, x, 0, x + w - 1,
412: h - 1, null);
413: g.dispose();
414: img = temp;
415: } else {
416: img = rasterizeFrame(null, 0, svgImage, params, time);
417: img = adjustImage(img, params);
418: }
419:
420: ByteArrayOutputStream buff = new ByteArrayOutputStream();
421: encodeImage(img, buff, params);
422:
423: if (ImageType.JPEG.equals(params.getImageType())) {
424: ByteArrayInputStream in = new ByteArrayInputStream(buff
425: .toByteArray());
426: img = decodeImage(in, params);
427: } else {
428: if (params.isTransparent()) {
429: int w = img.getWidth();
430: int h = img.getHeight();
431:
432: //draw checquered pattern to distinguish background
433: BufferedImage background = createBuffer(w, h, false);
434: Graphics g = background.createGraphics();
435: g.setColor(PATTERN_COLOR1);
436: g.fillRect(0, 0, w, h);
437: g.setColor(PATTERN_COLOR2);
438: int start = 0;
439: for (int y = 0; y < h; y += PATTERN_SIZE) {
440: for (int x = start; x < w; x += 2 * PATTERN_SIZE) {
441: g.fillRect(x, y, PATTERN_SIZE, PATTERN_SIZE);
442: }
443: start ^= PATTERN_SIZE;
444: }
445: g.drawImage(img, 0, 0, null);
446: g.dispose();
447: img = background;
448: }
449: }
450: return new PreviewInfo(img, params.getImageType().toString(),
451: buff.size());
452: }
453:
454: private static BufferedImage createBuffer(int w, int h,
455: boolean isTransparent) {
456: return new BufferedImage(w, h,
457: isTransparent ? BufferedImage.TYPE_INT_ARGB
458: : BufferedImage.TYPE_INT_RGB);
459: }
460:
461: public static BufferedImage rasterizeFrame(BufferedImage buffer,
462: int xOffset, SVGImage svgImage, Params params, float time) {
463: int w = params.getImageWidth();
464: int h = params.getImageHeight();
465:
466: // Create an offscreen buffer of the right size.
467: if (buffer == null) {
468: buffer = createBuffer(w, h, params.isTransparent());
469: xOffset = 0;
470: }
471:
472: // Create graphics to draw the image into.
473: Graphics g = buffer.createGraphics();
474: if (!params.isTransparent()) {
475: g.setColor(BACKGROUND_COLOR);
476: g.fillRect(xOffset, 0, w, h);
477: }
478:
479: synchronized (svgImage) {
480: // Scale the SVG image to the desired size.
481: float ratio = (float) w / svgImage.getViewportWidth();
482: if (svgImage.getViewportHeight() * ratio > h) {
483: ratio = (float) h / svgImage.getViewportHeight();
484: }
485: int _w = Math.round((svgImage.getViewportWidth() * ratio));
486: int _h = Math.round((svgImage.getViewportHeight() * ratio));
487: svgImage.setViewportWidth(_w);
488: svgImage.setViewportHeight(_h);
489: assert _w <= w;
490: assert _h <= h;
491:
492: // create instance of scalable graphics
493: ScalableGraphics sg = ScalableGraphics.createInstance();
494:
495: SVGSVGElement element = (SVGSVGElement) svgImage
496: .getDocument().getDocumentElement();
497: element.setCurrentTime(time);
498:
499: sg.bindTarget(g);
500: sg.render(xOffset + (w - _w) / 2, (h - _h) / 2, svgImage);
501: sg.releaseTarget();
502: }
503:
504: return buffer;
505: }
506:
507: private static BufferedImage rasterizeFramesInSingleImage(
508: SVGImage svgImage, Params params) {
509: int frameNum = params.getNumberFrames();
510: int w = params.getImageWidth();
511: int h = params.getImageHeight();
512: BufferedImage img = createBuffer(w * frameNum, h, params
513: .isTransparent());
514: for (int i = 0; i < frameNum; i++) {
515: rasterizeFrame(img, i * w, svgImage, params, params
516: .getStartTime()
517: + (i / params.getFramesPerSecond()));
518: }
519: img = adjustImage(img, params);
520: return img;
521: }
522:
523: public static FileObject rasterizeImage(SVGImage svgImage,
524: FileObject dir, String filenameRoot, Params params)
525: throws IOException {
526: FileObject file = null;
527: int frameNum = params.getNumberFrames();
528:
529: if (params.isInSingleImage()) {
530: BufferedImage img = rasterizeFramesInSingleImage(svgImage,
531: params);
532: FileObject fo = dir.createData(createFileName(filenameRoot,
533: params, -1, -1));
534:
535: writeImageToFile(img, fo, params);
536: file = fo;
537: } else {
538: for (int i = 0; i < frameNum; i++) {
539: BufferedImage img = rasterizeFrame(null, 0, svgImage,
540: params, params.getStartTime()
541: + (i / params.getFramesPerSecond()));
542: img = adjustImage(img, params);
543: FileObject fo = dir.createData(createFileName(
544: filenameRoot, params, i, frameNum));
545: writeImageToFile(img, fo, params);
546: }
547: }
548: return file;
549: }
550:
551: static final String getMessage(String stringID) {
552: return NbBundle.getMessage(AnimationRasterizer.class, stringID);
553: }
554:
555: private static int getEncodedSize(BufferedImage img, Params params)
556: throws IOException {
557: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
558: encodeImage(img, bOut, params);
559: return bOut.size();
560: }
561:
562: private static void checkInterrupted() throws InterruptedException {
563: if (Thread.interrupted()) {
564: throw new InterruptedException();
565: }
566: }
567:
568: interface ProgressUpdater {
569: void updateProgress(String text);
570: }
571:
572: static int calculateAnimationSize(SVGImage svgImage, Params params,
573: ProgressUpdater updater) throws IOException,
574: InterruptedException {
575: int size;
576: int frameNum = params.getNumberFrames();
577:
578: if (params.isInSingleImage()) {
579: int w = params.getImageWidth();
580: int h = params.getImageHeight();
581: BufferedImage img = createBuffer(w * frameNum, h, params
582: .isTransparent());
583: for (int i = 0; i < frameNum; i++) {
584: if (updater != null) {
585: updater.updateProgress(NbBundle
586: .getMessage(AnimationRasterizer.class,
587: "LBL_PreviewRasterizing", String
588: .valueOf(i), String
589: .valueOf(frameNum))); //NOI18N
590: }
591: rasterizeFrame(img, i * w, svgImage, params, params
592: .getStartTime()
593: + (i / params.getFramesPerSecond()));
594: }
595: checkInterrupted();
596: if (updater != null) {
597: updater
598: .updateProgress(getMessage("LBL_PreviewEncoding")); //NOI18N
599: }
600: img = adjustImage(img, params);
601: checkInterrupted();
602: size = getEncodedSize(img, params);
603: if (updater != null) {
604: updater.updateProgress(getSizeText(size));
605: }
606: } else {
607: size = 0;
608: for (int i = 0; i < frameNum; i++) {
609: BufferedImage img = rasterizeFrame(null, 0, svgImage,
610: params, params.getStartTime()
611: + (i / params.getFramesPerSecond()));
612: checkInterrupted();
613: img = adjustImage(img, params);
614: checkInterrupted();
615: size += getEncodedSize(img, params);
616: checkInterrupted();
617: }
618: }
619: return size;
620: }
621:
622: public static String getSizeText(int size) {
623: if (size < 1024) {
624: return size + " Bytes"; //NOI18N
625: } else if (size < 1024 * 1024) {
626: return (Math.round(size / 102.4) / 10.0) + " KBytes"; //NOI18N
627: } else {
628: return (Math.round(size / (102.4 * 1024)) / 10.0)
629: + " MBytes"; //NOI18N
630: }
631: }
632:
633: private static BufferedImage reduceColorsMedianCut(
634: BufferedImage image, Params params) {
635: int w = image.getWidth(), h = image.getHeight();
636: int[] pixels = new int[w * h];
637:
638: int i = 0;
639: for (int x = 0; x < w; x++) {
640: for (int y = 0; y < h; y++) {
641: int rgb = image.getRGB(x, y);
642: if ((rgb >>> 24) > 127) {
643: pixels[i++] = rgb;
644: } else {
645: pixels[i++] = pixels[0];
646: }
647: }
648: }
649: Quantizer quantizer = new Quantizer(pixels, w, h);
650: return quantizer.toImage();
651: }
652:
653: private static BufferedImage reduceColorsQuantize(
654: BufferedImage image, Params params) {
655: int w = image.getWidth(), h = image.getHeight();
656: int[][] pixels = new int[w][h];
657:
658: for (int x = 0; x < w; x++) {
659: for (int y = 0; y < h; y++) {
660: int rgb = image.getRGB(x, y);
661: if ((rgb >>> 24) > 127) {
662: pixels[x][y] = rgb;
663: } else {
664: pixels[x][y] = pixels[0][0];
665: }
666: }
667: }
668: boolean isTransparent = params.isTransparent();
669:
670: int[] palette = ShrinkPalette.quantizeImage(pixels,
671: isTransparent ? 255 : 256);
672:
673: byte[] red = new byte[256];
674: byte[] green = new byte[265];
675: byte[] blue = new byte[256];
676:
677: for (int i = 0; i < palette.length; i++) {
678: int rgb = palette[i];
679: //a = (rgb & 0xFF000000) >> 24;
680: red[i] = (byte) ((rgb & 0xFF0000) >> 16);
681: green[i] = (byte) ((rgb & 0xFF00) >> 8);
682: blue[i] = (byte) ((rgb & 0xFF));
683: }
684: int transparentColor = isTransparent ? 255 : -1;
685:
686: IndexColorModel colorModel = new IndexColorModel(8, 256, red,
687: green, blue, transparentColor);
688: BufferedImage bufferedImage = new BufferedImage(colorModel,
689: colorModel.createCompatibleWritableRaster(w, h), false,
690: null);
691: WritableRaster raster = bufferedImage.getRaster();
692: int[] pixelArray = new int[1];
693: for (int x = 0; x < w; x++) {
694: for (int y = 0; y < h; y++) {
695: int pixel = image.getRGB(x, y);
696: if ((pixel >>> 24) > 127) {
697: pixel = pixels[x][y];
698: } else {
699: pixel = transparentColor;
700: }
701: pixelArray[0] = pixel;
702: raster.setPixel(x, y, pixelArray);
703: }
704: }
705: return bufferedImage;
706: /*
707: Quantizer quantizer = new Quantizer(256, false, false);
708: return quantizer.quantizeImage(image);
709: */
710: }
711:
712: private static void writeImageToFile(BufferedImage image,
713: FileObject file, Params params) throws IOException {
714: OutputStream fout = file.getOutputStream();
715: try {
716: encodeImage(image, fout, params);
717: fout.flush();
718: } finally {
719: fout.close();
720: }
721: }
722:
723: private static void encodeImage(BufferedImage image,
724: OutputStream out, Params params) throws IOException {
725: Iterator<ImageWriter> writers = ImageIO
726: .getImageWritersByFormatName(params.getImageType()
727: .getName());
728: // these guys were found
729: ImageWriter writer = writers.hasNext() ? writers.next() : null;
730:
731: ImageWriteParam imageWriteParam = writer.getDefaultWriteParam();
732: if (imageWriteParam.canWriteProgressive()) {
733: imageWriteParam
734: .setProgressiveMode(params.isProgressive() ? ImageWriteParam.MODE_DEFAULT
735: : ImageWriteParam.MODE_DISABLED);
736: }
737:
738: if (imageWriteParam.canWriteCompressed()) {
739: imageWriteParam
740: .setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
741: imageWriteParam.setCompressionQuality(params
742: .getCompressionQuality());
743: }
744:
745: ImageOutputStream ios = ImageIO.createImageOutputStream(out);
746: writer.setOutput(ios);
747: writer.write(null, new IIOImage(image, null, null),
748: imageWriteParam);
749: writer.dispose();
750: ios.close();
751: }
752:
753: private static BufferedImage decodeImage(InputStream in,
754: Params params) throws IOException {
755: Iterator<ImageReader> readers = ImageIO
756: .getImageReadersByFormatName(params.getImageType()
757: .getName());
758: // these guys were found
759: ImageReader reader = readers.hasNext() ? readers.next() : null;
760:
761: ImageInputStream iis = ImageIO.createImageInputStream(in);
762: reader.setInput(iis);
763: BufferedImage img = reader.read(0);
764: reader.dispose();
765: iis.close();
766: return img;
767: }
768:
769: private static String getActiveConfigurationName(
770: FileObject primaryFile) {
771: Project p = FileOwnerQuery.getOwner(primaryFile);
772: if (p == null || !(p instanceof J2MEProject)) {
773: return ""; //NOI18N
774: }
775: return getDefaultName((J2MEProject) p);
776: }
777:
778: private static String getDefaultName(J2MEProject project) {
779: AntProjectHelper helper = project.getLookup().lookup(
780: AntProjectHelper.class);
781: EditableProperties ep = helper
782: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
783: ProjectConfigurationsHelper confs = project
784: .getConfigurationHelper();
785:
786: return confs.getActiveConfiguration() != confs
787: .getDefaultConfiguration() ? "_"
788: + confs.getActiveConfiguration().getDisplayName() : ""; //NOI18N
789: }
790: }
|