imagemodule.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 2,229 行 · 第 1/4 页
JAVA
2,229 行
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source 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. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */package com.caucho.quercus.lib;import com.caucho.quercus.QuercusException;import com.caucho.quercus.QuercusModuleException;import com.caucho.quercus.annotation.NotNull;import com.caucho.quercus.annotation.Optional;import com.caucho.quercus.annotation.ReturnNullAsFalse;import com.caucho.quercus.env.*;import com.caucho.quercus.module.AbstractQuercusModule;import com.caucho.util.L10N;import com.caucho.vfs.Path;import com.caucho.vfs.ReadStream;import com.caucho.vfs.WriteStream;import javax.imageio.ImageIO;import java.awt.*;import java.awt.color.ColorSpace;import java.awt.geom.*;import java.awt.image.*;import java.io.*;import java.util.*;import java.util.logging.*;/** * PHP image */public class ImageModule extends AbstractQuercusModule { private static final Logger log = Logger.getLogger(ImageModule.class.getName()); private static final L10N L = new L10N(ImageModule.class); public static final long IMG_GIF = 0x1; public static final long IMG_JPG = 0x2; public static final long IMG_JPEG = 0x2; public static final long IMG_PNG = 0x4; public static final long IMG_WBMP = 0x8; public static final long IMG_XPM = 0x10; public static final int IMAGETYPE_GIF = 1; public static final int IMAGETYPE_JPG = 2; public static final int IMAGETYPE_JPEG = 2; public static final int IMAGETYPE_PNG = 3; public static final int IMAGETYPE_SWF = 4; public static final int IMAGETYPE_PSD = 5; public static final int IMAGETYPE_BMP = 6; public static final int IMAGETYPE_TIFF_II = 7; public static final int IMAGETYPE_TIFF_MM = 8; public static final int IMAGETYPE_JPC = 9; public static final int IMAGETYPE_JP2 = 10; public static final int IMAGETYPE_JPX = 11; public static final int IMAGETYPE_JB2 = 12; public static final int IMAGETYPE_SWC = 13; public static final int IMAGETYPE_IFF = 14; public static final int IMAGETYPE_WBMP = 15; public static final int IMAGETYPE_XBM = 16; public static final int IMG_COLOR_STYLED = -2; public static final int IMG_COLOR_BRUSHED = -3; private static final int PNG_IHDR = pngCode("IHDR"); public static final int IMG_ARC_PIE = 0; public static final int IMG_ARC_CHORD = 1; public static final int IMG_ARC_NOFILL = 2; public static final int IMG_ARC_EDGED = 4; public static final int IMG_FILTER_NEGATE = 0; public static final int IMG_FILTER_GRAYSCALE = 1; public static final int IMG_FILTER_BRIGHTNESS = 2; public static final int IMG_FILTER_CONTRAST = 3; public static final int IMG_FILTER_COLORIZE = 4; public static final int IMG_FILTER_EDGEDETECT = 5; public static final int IMG_FILTER_EMBOSS = 6; public static final int IMG_FILTER_GAUSSIAN_BLUR = 7; public static final int IMG_FILTER_SELECTIVE_BLUR = 8; public static final int IMG_FILTER_MEAN_REMOVAL = 9; public static final int IMG_FILTER_SMOOTH = 10; public String []getLoadedExtensions() { return new String[] { "gd" }; } /** * Retrieve information about the currently installed GD library */ public static Value gd_info() { return (new ArrayValueImpl() .append(StringValue.create("GD Version"), // ] => 2.0 or higher StringValue.create("2.0 or higher")) .append(StringValue.create("FreeType Support"), // ] => 1 BooleanValue.TRUE) .append(StringValue.create("FreeType Linkage"), // ] => with freetype StringValue.create("with freetype")) .append(StringValue.create("T1Lib Support"), // ] => 1 BooleanValue.TRUE) .append(StringValue.create("GIF Read Support"), // ] => 1 BooleanValue.TRUE) .append(StringValue.create("GIF Create Support"), // ] => 1 BooleanValue.TRUE) .append(StringValue.create("JPG Support"), // ] => 1 BooleanValue.TRUE) .append(StringValue.create("PNG Support"), // ] => 1 BooleanValue.TRUE) .append(StringValue.create("WBMP Support"), // ] => 1 BooleanValue.TRUE) .append(StringValue.create("XPM Support"), // ] => BooleanValue.FALSE) .append(StringValue.create("XBM Support"), // ] => BooleanValue.FALSE) .append(StringValue.create("JIS-mapped Japanese Font Support"), // ] => BooleanValue.FALSE)); } /** * Returns the environment value. */ public Value getimagesize(Env env, Path file, @Optional ArrayValue imageArray) { if (! file.canRead()) return BooleanValue.FALSE; ImageInfo info = new ImageInfo(); ReadStream is = null; try { is = file.openRead(); if (! parseImageSize(is, info)) return BooleanValue.FALSE; } catch (Exception e) { log.log(Level.FINE, e.toString(), e); return BooleanValue.FALSE; } finally { is.close(); } if (imageArray == null) imageArray = new ArrayValueImpl(); imageArray.put(new LongValue(info._width)); imageArray.put(new LongValue(info._height)); imageArray.put(new LongValue(info._type)); imageArray.put(env.createString("width=\"" + info._width + "\" height=\"" + info._height + "\"")); if (info._bits >= 0) imageArray.put(env.createString("bits"), new LongValue(info._bits)); if (info._type == IMAGETYPE_JPEG) imageArray.put("channels", 3); if (info._mime != null) imageArray.put("mime", info._mime); return imageArray; } /** * Get file extension for image type */ public static Value image_type_to_extension(int imageType, boolean dot) { switch(imageType) { case IMAGETYPE_GIF: return StringValue.create(dot ? ".gif" : "gif"); case IMAGETYPE_JPG: return StringValue.create(dot ? ".jpg" : "jpg"); case IMAGETYPE_PNG: return StringValue.create(dot ? ".png" : "png"); case IMAGETYPE_SWF: return StringValue.create(dot ? ".swf" : "swf"); case IMAGETYPE_PSD: return StringValue.create(dot ? ".psd" : "psd"); case IMAGETYPE_BMP: return StringValue.create(dot ? ".bmp" : "bmp"); case IMAGETYPE_TIFF_II: return StringValue.create(dot ? ".tiff" : "tiff"); case IMAGETYPE_TIFF_MM: return StringValue.create(dot ? ".tiff" : "tiff"); case IMAGETYPE_JPC: return StringValue.create(dot ? ".jpc" : "jpc"); case IMAGETYPE_JP2: return StringValue.create(dot ? ".jp2" : "jp2"); case IMAGETYPE_JPX: return StringValue.create(dot ? ".jpf" : "jpf"); case IMAGETYPE_JB2: return StringValue.create(dot ? ".jb2" : "jb2"); case IMAGETYPE_SWC: return StringValue.create(dot ? ".swc" : "swc"); case IMAGETYPE_IFF: return StringValue.create(dot ? ".iff" : "iff"); case IMAGETYPE_WBMP: return StringValue.create(dot ? ".wbmp" : "wbmp"); case IMAGETYPE_XBM: return StringValue.create(dot ? ".xbm" : "xbm"); } throw new QuercusException("unknown imagetype " + imageType); } /** * Get Mime-Type for image-type returned by getimagesize, exif_read_data, * exif_thumbnail, exif_imagetype */ public static Value image_type_to_mime_type(int imageType) { switch(imageType) { case IMAGETYPE_GIF: return StringValue.create("image/gif"); case IMAGETYPE_JPG: return StringValue.create("image/jpeg"); case IMAGETYPE_PNG: return StringValue.create("image/png"); case IMAGETYPE_SWF: return StringValue.create("application/x-shockwave-flash"); case IMAGETYPE_PSD: return StringValue.create("image/psd"); case IMAGETYPE_BMP: return StringValue.create("image/bmp"); case IMAGETYPE_TIFF_II: return StringValue.create("image/tiff"); case IMAGETYPE_TIFF_MM: return StringValue.create("image/tiff"); case IMAGETYPE_JPC: return StringValue.create("application/octet-stream"); case IMAGETYPE_JP2: return StringValue.create("image/jp2"); case IMAGETYPE_JPX: return StringValue.create("application/octet-stream"); case IMAGETYPE_JB2: return StringValue.create("application/octet-stream"); case IMAGETYPE_SWC: return StringValue.create("application/x-shockwave-flash"); case IMAGETYPE_IFF: return StringValue.create("image/iff"); case IMAGETYPE_WBMP: return StringValue.create("image/vnd.wap.wbmp"); case IMAGETYPE_XBM: return StringValue.create("image/xbm"); } throw new QuercusException("unknown imageType " + imageType); } // XXX: image2wbmp /** * Returns a copy of the current transform */ public static AffineTransform image_get_transform(QuercusImage image) { if (image == null) return null; return image.getGraphics().getTransform(); } /** * Returns a copy of the current transform */ public static boolean image_set_transform(QuercusImage image, AffineTransform transform) { if (image == null) return false; image.getGraphics().setTransform(transform); return true; } /** * Set the blending mode for an image */ public static boolean imagealphablending(QuercusImage image, boolean useAlphaBlending) { image.getGraphics().setComposite(useAlphaBlending ? AlphaComposite.SrcOver : AlphaComposite.Src); return true; } /** * Should antialias functions be used or not */ public static boolean imageantialias(QuercusImage image, boolean useAntiAliasing) { image.getGraphics().setRenderingHint(RenderingHints.KEY_ANTIALIASING, useAntiAliasing ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF); return true; } /** * Draw a partial ellipse */ public static boolean imagearc(QuercusImage image, double cx, double cy, double width, double height, double start, double end, int color) { Arc2D arc = new Arc2D.Double(cx-width/2, cy-height/2, width, height, -1 * start, -1 *(end-start), Arc2D.OPEN); image.stroke(arc, color); return true; } /** * Draw a character horizontally */ public static boolean imagechar(QuercusImage image, int font, int x, int y, String c, int color) { Graphics2D g = image.getGraphics(); g.setColor(intToColor(color)); Font awtfont = image.getFont(font); int height = image.getGraphics().getFontMetrics(awtfont).getAscent(); g.setFont(awtfont); g.drawString(c.substring(0, 1), x, y+height); return true; } /** * Draw a character vertically */ public static boolean imagecharup(QuercusImage image, int font, int x, int y, String c, int color) { Graphics2D g = (Graphics2D)image.getGraphics().create(); g.rotate(-1 * Math.PI / 2); g.setColor(intToColor(color)); Font awtfont = image.getFont(font); int height = image.getGraphics().getFontMetrics(awtfont).getAscent(); g.setFont(awtfont); g.drawString(c.substring(0, 1), -1 * y, x+height); return true; } /** * Allocate a color for an image */ public static long imagecolorallocate(QuercusImage image, int r, int g, int b) { return (( 0x7f << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | ((b & 0xff) << 0)); } /** * Allocate a color for an image */ public static long imagecolorallocatealpha(QuercusImage image, int r, int g, int b, int a) { // PHP's alpha values are inverted and only 7 bits. int alpha = 0x7f - (a & 0xff); return ((alpha << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | ((b & 0xff) << 0) ); } /** * Get the index of the color of a pixel */ public static long imagecolorat(QuercusImage image, int x, int y) { return image.getPixel(x, y); } /** * Get the index of the closest color to the specified color */ public static long imagecolorclosest(QuercusImage image, int r, int g, int b) { return imagecolorallocate(image, r, g, b); } /** * Get the index of the closest color to the specified color + alpha */ public static long imagecolorclosestalpha(QuercusImage image, int r, int g, int b, int a) { return imagecolorallocatealpha(image, r, g, b, a); } /** * Get the index of the color which has the hue, white and blackness * nearest to the given color */ public static long imagecolorclosesthwb(QuercusImage image, int r, int g, int b) { throw new QuercusException("imagecolorclosesthwb is not supported"); } /** * De-allocate a color for an image */ public static boolean imagecolordeallocate(QuercusImage image, int rgb) { // no-op return true; } /** * Get the index of the specified color */ public static long imagecolorexact(QuercusImage image, int r, int g, int b) { return imagecolorallocate(image, r, g, b); } /** * Get the index of the specified color + alpha */ public static long imagecolorexactalpha(QuercusImage image, int r, int g, int b, int a) { return imagecolorallocatealpha(image, r, g, b, a); } /** * Makes the colors of the palette version of an image more closely * match the true color version */ public static boolean imagecolormatch(QuercusImage image1, QuercusImage image2) { // no-op return true; } /** * Get the index of the specified color or its closest possible alternative */ public static long imagecolorresolve(QuercusImage image, int r, int g, int b) { return imagecolorallocate(image, r, g, b); } /** * Get the index of the specified color + alpha or its closest possible * alternative */ public static long imagecolorresolvealpha(QuercusImage image, int r, int g, int b, int a) { return imagecolorallocatealpha(image, r, g, b, a); } /** * Set the color for the specified palette index */ public static boolean imagecolorset(QuercusImage image, int index, int r, int g, int b) { // no-op since we currently only support true-color, full-alpha channel return true; } /** * Get the colors for an index */ public static ArrayValue imagecolorsforindex(QuercusImage image, int argb) { ArrayValue arrayValue = new ArrayValueImpl(); arrayValue.put("red", (argb >> 16) & 0xff); arrayValue.put("green", (argb >> 8) & 0xff); arrayValue.put("blue", (argb >> 0) & 0xff); // PHP's alpha is backwards from the rest of the world... int alpha = 0x7f - ((argb >> 24) & 0xff); arrayValue.put("alpha", alpha); return arrayValue; } /** * Find out the number of colors in an image's palette */ public static Value imagecolorstotal() { return LongValue.create(0); } /** * Define a color as transparent */ public static long imagecolortransparent(QuercusImage image, @Optional int color) { // form that includes the optional argument is a no-op since we // currently only support true-color, full-alpha channel return 0xFF000000; } /** * Apply a 3x3 convolution matrix, using coefficient div and offset */ public static boolean imageconvolution(QuercusImage image, ArrayValue matrix, double div, double offset) { // XXX: implement div and offset float[] kernelValues = new float[9]; for(int y = 0; y < 3; y++) { for(int x = 0; x < 3; x++) { kernelValues[x + y * 3] = (float) matrix.get(LongValue.create(y)) .get(LongValue.create(x)).toDouble(); } } ConvolveOp convolveOp = new ConvolveOp(new Kernel(3, 3, kernelValues), ConvolveOp.EDGE_NO_OP, null); BufferedImage bufferedImage = convolveOp.filter(image._bufferedImage, null); image._bufferedImage.getGraphics().drawImage(bufferedImage, 1, 0, null); return true; } /** * Copy part of an image */ public static boolean imagecopy(QuercusImage dest, QuercusImage src, int dx, int dy, int sx, int sy, int w, int h) { dest.getGraphics().drawImage(src._bufferedImage, dx, dy, dx+w, dy+h,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?