imagemodule.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 2,229 行 · 第 1/4 页

JAVA
2,229
字号
  {    // don't forget: PHP alpha channel is only 7 bits    int alpha = argb >> 24;    alpha <<= 1;    alpha |= ((alpha & 0x2) >> 1);  // copy bit #2 to LSB    return new Color((argb >> 16) & 0xff,		     (argb >>  8) & 0xff,		     (argb >>  0) & 0xff,		     alpha);  }  /**   * Parses the image size from the file.   */  private static boolean parseImageSize(ReadStream is, ImageInfo info)    throws IOException  {    int ch;    ch = is.read();    if (ch == 137) {      // PNG - http://www.libpng.org/pub/png/spec/iso/index-object.html      if (is.read() != 'P' ||          is.read() != 'N' ||          is.read() != 'G' ||          is.read() != '\r' ||          is.read() != '\n' ||          is.read() != 26 ||          is.read() != '\n')        return false;      return parsePNGImageSize(is, info);    }    else if (ch == 'G') {      // GIF      if (is.read() != 'I' ||          is.read() != 'F' ||          is.read() != '8' ||          ((ch = is.read()) != '7' && ch != '9') ||          is.read() != 'a')        return false;      return parseGIFImageSize(is, info);    }    else if (ch == 0xff) {      // JPEG      if (is.read() != 0xd8)        return false;      return parseJPEGImageSize(is, info);    }    else      return false;  }  /**   * Parses the image size from the PNG file.   */  private static boolean parsePNGImageSize(ReadStream is, ImageInfo info)    throws IOException  {    int length;    while ((length = readInt(is)) > 0) {      int type = readInt(is);      if (type == PNG_IHDR) {	int width = readInt(is);	int height = readInt(is);	int depth = is.read() & 0xff;	int color = is.read() & 0xff;	int compression = is.read() & 0xff;	int filter = is.read() & 0xff;	int interlace = is.read() & 0xff;	info._width = width;	info._height = height;	info._type = IMAGETYPE_PNG;	info._bits = depth;	info._mime = "image/png";	return true;      }      else {	for (int i = 0; i < length; i++) {	  if (is.read() < 0)	    return false;	}      }      int crc = readInt(is);    }    return false;  }  /**   * Parses the image size from the PNG file.   */  private static boolean parseGIFImageSize(ReadStream is, ImageInfo info)    throws IOException  {    int length;    int width = (is.read() & 0xff) + 256 * (is.read() & 0xff);    int height = (is.read() & 0xff) + 256 * (is.read() & 0xff);    int flags = is.read() & 0xff;    info._width = width;    info._height = height;    info._type = IMAGETYPE_GIF;    info._bits = flags & 0x7;    info._mime = "image/gif";    return true;  }  /**   * Parses the image size from the PNG file.   */  private static boolean parseJPEGImageSize(ReadStream is, ImageInfo info)    throws IOException  {    int ch;    while ((ch = is.read()) == 0xff) {      ch = is.read();      if (ch == 0xff) {	is.unread();      }      else if (0xd0 <= ch && ch <= 0xd9) {	// rst      }      else if (0x01 == ch) {	// rst      }      else if (ch == 0xc0) {	int len = 256 * is.read() + is.read();	int bits = is.read();	int height = 256 * is.read() + is.read();	int width = 256 * is.read() + is.read();	info._width = width;	info._height = height;	info._type = IMAGETYPE_JPEG;	info._bits = bits;	info._mime = "image/jpeg";	return true;      }      else {	int len = 256 * is.read() + is.read();	is.skip(len - 2);      }    }    return false;  }  private static int pngCode(String code)  {    return ((code.charAt(0) << 24) |	    (code.charAt(1) << 16) |	    (code.charAt(2) << 8) |	    (code.charAt(3)));  }  private static int readInt(ReadStream is)    throws IOException  {    return (((is.read() & 0xff) << 24) |	    ((is.read() & 0xff) << 16) |	    ((is.read() & 0xff) << 8) |	    ((is.read() & 0xff)));  }  // Inner Classes ////////////////////////////////////////////////////////  static class ImageInfo {    int _width;    int _height;    int _type;    int _bits;    String _mime;  }  public static class QuercusImage extends ResourceValue {    private HashMap<String,Font> _fontMap = new HashMap<String,Font>();    private Font []_fontArray = new Font[6];        private int _width;    private int _height;    BufferedImage _bufferedImage;    private Graphics2D _graphics;    private boolean _isInterlace;    private BufferedImage _brush;    private int[] _style;    private int _thickness;    public QuercusImage(int width, int height)    {      _width = width;      _height = height;      _bufferedImage =	new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);      _graphics = (Graphics2D)_bufferedImage.getGraphics();    }    public QuercusImage(InputStream inputStream)    {      try {	_bufferedImage = ImageIO.read(inputStream);	_width = _bufferedImage.getWidth(null);	_height = _bufferedImage.getHeight(null);	_graphics = (Graphics2D)_bufferedImage.getGraphics();      }      catch (IOException e) {	throw new QuercusException(e);      }    }    public QuercusImage(Env env, Path filename)    {      try {	_bufferedImage = ImageIO.read(filename.openRead());	_width = _bufferedImage.getWidth(null);	_height = _bufferedImage.getHeight(null);	_graphics = (Graphics2D)_bufferedImage.getGraphics();      }      catch (IOException e) {	throw new QuercusException(e);      }    }    public String toString()    {      return "resource(Image)";    }    public void setInterlace(boolean isInterlace)    {      _isInterlace = isInterlace;    }    public boolean isInterlace()    {      return _isInterlace;    }    public int getPixel(int x, int y)    {      return _bufferedImage.getRGB(x, y);    }    public void setPixel(int x, int y, int color)    {      _bufferedImage.setRGB(x, y, color);    }    public Graphics2D getGraphics()    {      return _graphics;    }    public Font getFont(int fontIndex)    {      if (fontIndex < 0)	fontIndex = 0;      else if (fontIndex > 5)	fontIndex = 5;      Font font = _fontArray[fontIndex];      if (font == null) {	switch (fontIndex) {	case 0: case 1:	  font = new Font("sansserif", 0, 8);	  break;	case 2:	  font = new Font("sansserif", 0, 10);	  break;	case 3:	  font = new Font("sansserif", 0, 11);	  break;	case 4:	  font = new Font("sansserif", 0, 12);	  break;	default:	  font = new Font("sansserif", 0, 14);	  break;	}	_fontArray[fontIndex] = font;      }      return font;    }    public Font getTrueTypeFont(Env env, String fontPath)      throws FontFormatException,	     IOException    {      Font font = _fontMap.get(fontPath);      if (font != null)	return font;      Path pwd = env.getPwd();      Path path = pwd.lookup(fontPath);      if (path.canRead()) {	ReadStream is = path.openRead();	try {	  font = Font.createFont(Font.TRUETYPE_FONT, is);	} finally {	  is.close();	}	_fontMap.put(fontPath, font);	return font;      }      if (fontPath.startsWith("/"))	return null;      StringValue gdFontPathKey = env.createString("GDFONTPATH");            String gdFontPath = OptionsModule.getenv(env, gdFontPathKey).toString();      for (String item : gdFontPath.split("[:;]")) {	path = pwd.lookup(item).lookup(fontPath);	if (path.canRead()) {	  ReadStream is = path.openRead();	  try {	    font = Font.createFont(Font.TRUETYPE_FONT, is);	  } finally {	    is.close();	  }	  _fontMap.put(fontPath, font);	  return font;	}      }      return null;    }    public int getWidth()    {      return _bufferedImage.getWidth(null);    }    public int getHeight()    {      return _bufferedImage.getHeight(null);    }    public void fill(Shape shape, int color)    {      _graphics.setColor(intToColor(color));      _graphics.fill(shape);    }    public void stroke(Shape shape, int color)    {      switch(color)	{	  case IMG_COLOR_STYLED:	    strokeStyled(shape);	    break;	  case IMG_COLOR_BRUSHED:	    strokeBrushed(shape);	    break;	  default:	    _graphics.setColor(intToColor(color));	    _graphics.setStroke(new BasicStroke(_thickness));	    _graphics.draw(shape);	    break;	}    }        private void strokeStyled(Shape shape)    {      for(int i=0; i<_style.length; i++)	{	  _graphics.setColor(intToColor(_style[i]));	  Stroke stroke =	    new BasicStroke(_thickness,			    BasicStroke.JOIN_ROUND, BasicStroke.CAP_ROUND, 1,			    new float[] { 1, _style.length-1 },			    i);	  _graphics.setStroke(stroke);	  _graphics.draw(shape);	}    }    private void strokeBrushed(Shape shape)    {      // XXX: support "styled brushes" (see imagesetstyle() example on php.net)      Graphics2D g = _graphics;      FlatteningPathIterator fpi =	new FlatteningPathIterator(shape.getPathIterator(g.getTransform()), 1);      float[] floats = new float[6];      fpi.currentSegment(floats);      float last_x = floats[0];      float last_y = floats[1];      while(! fpi.isDone())	{	  fpi.currentSegment(floats);	  int distance = (int)Math.sqrt((floats[0]-last_x)*(floats[0]-last_x)+					(floats[1]-last_y)*(floats[1]-last_y));	  if (distance <= 1) distance = 1;	  for(int i=1; i<=distance; i++)	    {	      int x = (int)(floats[0]*i+last_x*(distance-i))/distance;	      x -= _brush.getWidth() / 2;	      int y = (int)(floats[1]*i+last_y*(distance-i))/distance;	      y -= _brush.getHeight() / 2;	      g.drawImage(_brush, x, y, null);	    }	  last_x = floats[0];	  last_y = floats[1];	  fpi.next();	}    }    public void setThickness(int thickness)    {      _style = null;      _thickness = thickness;    }    public void setStyle(Env env, ArrayValue colors)    {      _style = new int[colors.getSize()];            Iterator<Value> iter = colors.getValueIterator(env);      for(int i = 0; i < _style.length; i++) {	    _style[i] = iter.next().toInt();	  }    }    public void setBrush(QuercusImage image)    {      _brush = image._bufferedImage;    }    public BufferedImage getBrush()    {      return _brush;    }    public void flood(int x, int y, int color)    {      flood(x, y, color, 0, false);    }    public void flood(int x, int y, int color, int border)    {      flood(x, y, color, border, true);    }    private void flood(int startx, int starty, int color, int border, boolean useBorder)    {      java.util.Queue<Integer> xq = new LinkedList<Integer>();      java.util.Queue<Integer> yq = new LinkedList<Integer>();      xq.add(startx);      yq.add(starty);      color &= 0x00ffffff;      border &= 0x00ffffff;            int height = getHeight();      while(xq.size() > 0)      {        int x = xq.poll();        int y = yq.poll();        int p = (getPixel(x, y) & 0x00ffffff);        if (useBorder ? (p==border||p==color) : (p != 0)) continue;        setPixel(x, y, color);        for(int i = x - 1; i >= 0; i--)        {          p = (getPixel(i, y) & 0x00ffffff);          if (useBorder ? (p==border||p==color) : (p!= 0)) break;          setPixel(i, y, color);          if (y + 1 < height) {            xq.add(i);            yq.add(y+1);          }                    if (y - 1 >= 0) {            xq.add(i);            yq.add(y-1);          }        }        for(int i = x + 1; i < getWidth(); i++)        {          p = (getPixel(i, y) & 0x00ffffff);          if (useBorder ? (p==border||p==color) : (p != 0)) break;          setPixel(i, y, color);                    if (y + 1 < height) {            xq.add(i);            yq.add(y+1);          }                    if (y - 1 >= 0) {            xq.add(i);            yq.add(y-1);          }        }        if (y + 1 < height) {          xq.add(x);          yq.add(y+1);        }                if (y - 1 >= 0) {          xq.add(x);          yq.add(y-1);        }      }    }  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?