Simple, functional ImageWriterSpi used to understand how information : 图像输入输出 « 图形用户界面 « Java

En
Java
1. 图形用户界面
2. 三维图形动画
3. 高级图形
4. 蚂蚁编译
5. Apache类库
6. 统计图
7. 
8. 集合数据结构
9. 数据类型
10. 数据库JDBC
11. 设计模式
12. 开发相关类
13. EJB3
14. 电子邮件
15. 事件
16. 文件输入输出
17. 游戏
18. 泛型
19. GWT
20. Hibernate
21. 本地化
22. J2EE平台
23. 基于J2ME
24. JDK-6
25. JNDI的LDAP
26. JPA
27. JSP技术
28. JSTL
29. 语言基础知识
30. 网络协议
31. PDF格式RTF格式
32. 映射
33. 常规表达式
34. 脚本
35. 安全
36. Servlets
37. Spring
38. Swing组件
39. 图形用户界面
40. SWT-JFace-Eclipse
41. 线程
42. 应用程序
43. Velocity
44. Web服务SOA
45. 可扩展标记语言
Java 教程
Java » 图形用户界面 » 图像输入输出屏幕截图 
Simple, functional ImageWriterSpi used to understand how information
  
/*

Java Media APIs: Cross-Platform Imaging, Media and Visualization
Alejandro Terrazas
Sams, Published November 2002, 
ISBN 0672320940
*/


import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.IOException;
import java.util.Locale;

import javax.imageio.IIOImage;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataFormat;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.spi.ImageWriterSpi;
import javax.imageio.stream.ImageOutputStream;

import org.w3c.dom.Node;

/**
 * Simple, functional ImageWriterSpi used to understand how information
 * regarding format name, suffices and mime types get passed to ImageIO static
 * methods
 */
public class ch5ImageWriterSpi extends ImageWriterSpi {

  static final String[] suffixes = "ch5""CH5" };

  static final String[] names = "ch5" };

  static final String[] MIMETypes = "image/ch5" };

  static final String version = "1.00";

  static final String writerClassName = "ch5.imageio.plugins.ch5ImageWriter";

  static final String vendorName = "Company Name";

  static final String[] readerSpiNames = "ch5.imagio.plugins.ch5ImageReaderSpi" };

  /*
   * static final String nativeStreamMetadataFormatName =
   * "ch5.imageio.ch5stream_1.0"; static final String[]
   * streamMetadataFormatNames = {nativeStreamMetadataFormatName}; static
   * final String nativeImageMetadataFormatName = "ch5.imageio.ch5image_1.0";
   * static final String[] imageMetadataFormatNames =
   * {nativeImageMetadataFormatName};
   */

  static final String nativeStreamMetadataFormatName = "ch5.imageio.ch5stream_1.00";

  static final String nativeStreamMetadataFormatClassName = "ch5.imageio.ch5stream";

  static final String[] extraStreamMetadataFormatNames = null };

  static final String[] extraStreamMetadataFormatClassNames = null };

  static final String nativeImageMetadataFormatName = "ch5.imageio.ch5image_1.00";

  static final String nativeImageMetadataFormatClassName = "ch5.imageio.ch5image";

  static final String[] extraImageMetadataFormatNames = null };

  static final String[] extraImageMetadataFormatClassNames = null };

  public ch5ImageWriterSpi() {
    super(vendorName, version, names, suffixes, MIMETypes, writerClassName,
        STANDARD_OUTPUT_TYPE, readerSpiNames, false,
        nativeStreamMetadataFormatName,
        nativeStreamMetadataFormatClassName,
        extraStreamMetadataFormatNames,
        extraStreamMetadataFormatClassNames, false,
        nativeImageMetadataFormatName,
        nativeImageMetadataFormatClassName,
        extraImageMetadataFormatNames,
        extraImageMetadataFormatClassNames);

  }

  public String getDescription(Locale locale) {
    return "Demo ch5 image writer, version " + version;
  }

  public ImageWriter createWriterInstance(Object extension) {
    return new ch5ImageWriter(this);
  }

  /**
   * This method gets called when an application wants to see if the
   * corresponding ImageWriter can encode an image with a ColorModel and
   * SampleModel specified by the ImageTypeSpecifier
   */
  public boolean canEncodeImage(ImageTypeSpecifier its) {
    if (its.getBufferedImageType() == BufferedImage.TYPE_BYTE_GRAY)
      return true;
    else
      return false;
  }
}

class ch5v1ImageWriter extends ImageWriter {

  public ch5v1ImageWriter(ImageWriterSpi originatingProvider) {
    super(originatingProvider);
    streamMetadataWritten = false;
  }

  /**
   * this method returns null for now. We will revisit it at the end of this
   * chapter after metadata has been discussed.
   */
  public IIOMetadata convertImageMetadata(IIOMetadata metadata,
      ImageTypeSpecifier its, ImageWriteParam param) {
    return null;
  }

  /**
   * this method returns null for now. We will revisit it at the end of this
   * chapter after metadata has been discussed.
   */
  public IIOMetadata convertStreamMetadata(IIOMetadata metadata,
      ImageWriteParam param) {
    return null;
  }

  /**
   * this method returns null for now. We will revisit it at the end of this
   * chapter after metadata has been discussed.
   */
  public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier its,
      ImageWriteParam param) {
    return null;
  }

  /**
   * this method returns null for now. We will revisit it at the end of this
   * chapter after metadata has been discussed.
   */
  public IIOMetadata getDefaultStreamMetadata(ImageWriteParam param) {
    return null;
  }

  /**
   * write out the output image specified by index imageIndex using the
   * parameters specified by the ImageWriteParam object param
   */
  public void write(IIOMetadata metadata, IIOImage iioimage,
      ImageWriteParam param) {
    Node root = null;
    Node dimensionsElementNode = null;

    if (iioimage.getRenderedImage() != null)
      raster = iioimage.getRenderedImage().getData();
    else
      raster = iioimage.getRaster();

    /*
     * since this format allows you to write multiple images, the
     * streamMetadataWritten variable makes sure the stream metadata is
     * written only once. Not using metadata in this version, so using
     * default value of 1 image per output stream.
     */
    if (streamMetadataWritten == false) {
      try {
        ios.writeBytes("5\n");
        ios.writeBytes("1");
        ios.flush();
      catch (IOException ioe) {
        System.err.println("IOException " + ioe.getMessage());
      }
      streamMetadataWritten = true;
    }

    int sourceWidth = raster.getWidth();
    int sourceHeight = raster.getHeight();
    int destinationWidth = -1;
    int destinationHeight = -1;
    int sourceRegionWidth = -1;
    int sourceRegionHeight = -1;
    int sourceRegionXOffset = -1;
    int sourceRegionYOffset = -1;
    int xSubsamplingFactor = -1;
    int ySubsamplingFactor = -1;

    if (param == null)
      param = getDefaultWriteParam();

    /*
     * get Rectangle object which will be used to clip the source image's
     * dimensions.
     */
    Rectangle sourceRegion = param.getSourceRegion();
    if (sourceRegion != null) {
      sourceRegionWidth = (intsourceRegion.getWidth();
      sourceRegionHeight = (intsourceRegion.getHeight();
      sourceRegionXOffset = (intsourceRegion.getX();
      sourceRegionYOffset = (intsourceRegion.getY();

      /*
       * correct for overextended source regions
       */
      if (sourceRegionXOffset + sourceRegionWidth > sourceWidth)
        destinationWidth = sourceWidth - sourceRegionXOffset;
      else
        destinationWidth = sourceRegionWidth;

      if (sourceRegionYOffset + sourceRegionHeight > sourceHeight)
        destinationHeight = sourceHeight - sourceRegionYOffset;
      else
        destinationHeight = sourceRegionHeight;
    else {
      destinationWidth = sourceWidth;
      destinationHeight = sourceHeight;
      sourceRegionXOffset = sourceRegionYOffset = 0;
    }
    /*
     * get subsampling factors
     */
    xSubsamplingFactor = param.getSourceXSubsampling();
    ySubsamplingFactor = param.getSourceYSubsampling();

    destinationWidth = (destinationWidth - 1/ xSubsamplingFactor + 1;
    destinationHeight = (destinationHeight - 1/ ySubsamplingFactor + 1;

    byte[] sourceBuffer;
    byte[] destinationBuffer = new byte[destinationWidth];

    try {
      ios.writeBytes(new String("\n"));
      ios.writeBytes(new String(destinationWidth + "\n"));
      ios.writeBytes(new String(destinationHeight + "\n"));

      int jj;
      int index;
      for (int j = 0; j < sourceWidth; j++) {
        sourceBuffer = (byte[]) raster.getDataElements(0, j,
            sourceWidth, 1null);
        jj = j - sourceRegionYOffset;
        if (jj % ySubsamplingFactor == 0) {
          jj /= ySubsamplingFactor;
          if ((jj >= 0&& (jj < destinationHeight)) {
            for (int i = 0; i < destinationWidth; i++) {
              index = sourceRegionXOffset + i
                  * xSubsamplingFactor;
              destinationBuffer[i= sourceBuffer[index];
            }
            ios.write(destinationBuffer, 0, destinationWidth);
            ios.flush();
          }
        }
      }
    catch (IOException e) {
      System.err.println("IOException: " + e.getMessage());
    }
  }

  public void setOutput(Object output) {
    super.setOutput(output);

    if (output == null)
      throw new IllegalArgumentException("output is null");

    if (!(output instanceof ImageOutputStream))
      throw new IllegalArgumentException(
          "output not an ImageOutputStream");

    ios = (ImageOutputStreamoutput;
    streamMetadataWritten = false;
  }

  private ImageOutputStream ios;

  private boolean streamMetadataWritten;

  private Raster raster;
}

class ch5ImageWriter extends ImageWriter {

  public ch5ImageWriter(ImageWriterSpi originatingProvider) {
    super(originatingProvider);
    streamMetadataWritten = false;
  }

  /**
   * this method is used to convert an ImageReader's image metadata which is
   * in a particular format into image metadata that can be used for this
   * ImageWriter. Primarily this is used for transcoding (format conversion).
   * This ImageWriter does not support such conversions
   */
  public IIOMetadata convertImageMetadata(IIOMetadata metadata,
      ImageTypeSpecifier specifier, ImageWriteParam param) {
    return null;
  }

  /**
   * this method is used to convert an ImageReader's stream metadata which is
   * in a particular format into stream metadata that can be used for this
   * ImageWriter. Primarily this is used for transcoding (format conversion).
   * This ImageWriter does not support such conversions
   */
  public IIOMetadata convertStreamMetadata(IIOMetadata metadata,
      ImageWriteParam param) {
    return null;
  }

  /**
   * provide default values for the image metadata
   */
  public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier specifier,
      ImageWriteParam param) {
    ch5ImageMetadata imagemd = new ch5ImageMetadata();
    int width = raster.getWidth();
    int height = raster.getHeight();
    imagemd.initialize(width, height)// default image size
    return imagemd;
  }

  /**
   * provide default values for the stream metadata
   */
  public IIOMetadata getDefaultStreamMetadata(ImageWriteParam param) {
    ch5StreamMetadata streammd = new ch5StreamMetadata();
    streammd.initialize(1)// default number of images
    return streammd;
  }

  /**
   * write out the output image specified by index imageIndex using the
   * parameters specified by the ImageWriteParam object param
   */
  public void write(IIOMetadata metadata, IIOImage iioimage,
      ImageWriteParam param) {
    Node root = null;
    Node dimensionsElementNode = null;

    if (iioimage.getRenderedImage() != null)
      raster = iioimage.getRenderedImage().getData();
    else
      raster = iioimage.getRaster();

    /*
     * since this format allows you to write multiple images, the
     * streamMetadataWritten variable makes sure the stream metadata is
     * written only once
     */
    if (streamMetadataWritten == false) {
      if (metadata == null)
        metadata = getDefaultStreamMetadata(param);
      root = metadata.getAsTree("ch5.imageio.ch5stream_1.00");
      dimensionsElementNode = root.getFirstChild();
      Node numberImagesAttributeNode = dimensionsElementNode
          .getAttributes().getNamedItem("numberImages");
      String numberImages = numberImagesAttributeNode.getNodeValue();
      try {
        ios.writeBytes("5\n");
        ios.writeBytes(numberImages);
        ios.flush();
      catch (IOException ioe) {
        System.err.println("IOException " + ioe.getMessage());
      }
      streamMetadataWritten = true;
    }

    String widthString;
    String heightString;
    IIOMetadata imageMetadata = (ch5ImageMetadataiioimage.getMetadata();
    /*
     * don't really need image metadata object here since raster knows
     * necessary information
     */
    if (imageMetadata == null)
      imageMetadata = getDefaultImageMetadata(null, param);

    root = imageMetadata.getAsTree("ch5.imageio.ch5image_1.00");
    dimensionsElementNode = root.getFirstChild();

    Node widthAttributeNode = dimensionsElementNode.getAttributes()
        .getNamedItem("imageWidth");
    widthString = widthAttributeNode.getNodeValue();

    Node heightAttributeNode = dimensionsElementNode.getAttributes()
        .getNamedItem("imageHeight");
    heightString = heightAttributeNode.getNodeValue();

    int sourceWidth = Integer.parseInt(widthString);
    int sourceHeight = Integer.parseInt(heightString);
    int destinationWidth = -1;
    int destinationHeight = -1;
    int sourceRegionWidth = -1;
    int sourceRegionHeight = -1;
    int sourceRegionXOffset = -1;
    int sourceRegionYOffset = -1;
    int xSubsamplingFactor = -1;
    int ySubsamplingFactor = -1;

    if (param == null)
      param = getDefaultWriteParam();

    /*
     * get Rectangle object which will be used to clip the source image's
     * dimensions.
     */
    Rectangle sourceRegion = param.getSourceRegion();
    if (sourceRegion != null) {
      sourceRegionWidth = (intsourceRegion.getWidth();
      sourceRegionHeight = (intsourceRegion.getHeight();
      sourceRegionXOffset = (intsourceRegion.getX();
      sourceRegionYOffset = (intsourceRegion.getY();

      /*
       * correct for overextended source regions
       */
      if (sourceRegionXOffset + sourceRegionWidth > sourceWidth)
        destinationWidth = sourceWidth - sourceRegionXOffset;
      else
        destinationWidth = sourceRegionWidth;

      if (sourceRegionYOffset + sourceRegionHeight > sourceHeight)
        destinationHeight = sourceHeight - sourceRegionYOffset;
      else
        destinationHeight = sourceRegionHeight;
    else {
      destinationWidth = sourceWidth;
      destinationHeight = sourceHeight;
      sourceRegionXOffset = sourceRegionYOffset = 0;
    }
    /*
     * get subsampling factors
     */
    xSubsamplingFactor = param.getSourceXSubsampling();
    ySubsamplingFactor = param.getSourceYSubsampling();

    destinationWidth = (destinationWidth - 1/ xSubsamplingFactor + 1;
    destinationHeight = (destinationHeight - 1/ ySubsamplingFactor + 1;

    byte[] sourceBuffer;
    byte[] destinationBuffer = new byte[destinationWidth];

    try {
      ios.writeBytes(new String("\n"));
      ios.writeBytes(new String(destinationWidth + "\n"));
      ios.writeBytes(new String(destinationHeight + "\n"));

      int jj;
      int index;
      for (int j = 0; j < sourceWidth; j++) {
        sourceBuffer = (byte[]) raster.getDataElements(0, j,
            sourceWidth, 1null);
        jj = j - sourceRegionYOffset;
        if (jj % ySubsamplingFactor == 0) {
          jj /= ySubsamplingFactor;
          if ((jj >= 0&& (jj < destinationHeight)) {
            for (int i = 0; i < destinationWidth; i++) {
              index = sourceRegionXOffset + i
                  * xSubsamplingFactor;
              destinationBuffer[i= sourceBuffer[index];
            }
            ios.write(destinationBuffer, 0, destinationWidth);
            ios.flush();
          }
        }
      }
    catch (IOException e) {
      System.err.println("IOException: " + e.getMessage());
    }
  }

  public void setOutput(Object output) {
    super.setOutput(output);

    if (output == null)
      throw new IllegalArgumentException("output is null");

    if (!(output instanceof ImageOutputStream))
      throw new IllegalArgumentException(
          "output not an ImageOutputStream");

    ios = (ImageOutputStreamoutput;
    streamMetadataWritten = false;
  }

  private ImageOutputStream ios;

  private boolean streamMetadataWritten;

  private Raster raster;
}


/**
 * ch5ImageMetadata.java -- holds image metadata for the ch5 format.
 * The internal tree for holding this metadata is read only
 */
class ch5ImageMetadata extends IIOMetadata {
    static final String
        nativeMetadataFormatName = "ch5.imageio.ch5image_1.00";
    static final String
        nativeMetadataFormatClassName = "ch5.imageio.ch5image";

    static final String[] extraMetadataFormatNames = null;
    static final String[] extraMetadataFormatClassNames = null;

    static final boolean standardMetadataFormatSupported = false;

    public int imageWidth;
    public int imageHeight;

    public ch5ImageMetadata() {
  super(standardMetadataFormatSupported,
        nativeMetadataFormatName, 
        nativeMetadataFormatClassName,
        extraMetadataFormatNames,
        extraMetadataFormatClassNames
        );
  imageWidth = -1;
  imageHeight = -1;
    }
    
    public boolean isReadOnly() {
        return true;
    }

    /**
     * IIOMetadataFormat objects are meant to describe the structure of
     * metadata returned from the getAsTree method.  In this case,
     * no such description is available
     */
    public IIOMetadataFormat getMetadataFormat(String formatName) {
        if (formatName.equals(nativeMetadataFormatName)) {
            return null;
        else {
            throw new IllegalArgumentException("Unrecognized format!");
        }
    }

    /**
     * returns the image metadata in a tree corresponding to the
     * provided formatName
     */
    public Node getAsTree(String formatName) {
        if (formatName.equals(nativeMetadataFormatName)) {
            return getNativeTree();
        else {
            throw new IllegalArgumentException("Unrecognized format!");
        }
    }

    /**
     * returns the image metadata in a tree using the following format
     * <!ELEMENT ch5.imageio.ch5image_1.00 (imageDimensions)>
     * <!ATTLIST imageDimensions
     *      imageWidth   CDATA  #REQUIRED
     *      imageHeight  CDATA  #REQUIRED
     */
    private Node getNativeTree() {
        IIOMetadataNode root =
            new IIOMetadataNode(nativeMetadataFormatName);

        IIOMetadataNode node = new IIOMetadataNode("imageDimensions");
        node.setAttribute("imageWidth", Integer.toString(imageWidth));
        node.setAttribute("imageHeight", Integer.toString(imageHeight));
        root.appendChild(node);

        return root;
    }

    public void setFromTree(String formatName, Node root) {
        throw new IllegalStateException("Metadata is read-only!");
    }

    public void mergeTree(String formatName, Node root) {
        throw new IllegalStateException("Metadata is read-only!");
    }

    public void reset() {
        throw new IllegalStateException("Metadata is read-only!");
    }

    /**
     * initialize the image metadata elements width and height
     */
    public void initialize(int width, int height) {
  imageWidth = width;
  imageHeight = height;
    }
}



/**
 * ch5StreamMetadata.java -- holds stream metadata for the ch5 format. The
 * internal tree for holding this metadata is read only
 */

class ch5StreamMetadata extends IIOMetadata {
  static final String nativeMetadataFormatName = "ch5.imageio.ch5stream_1.00";

  static final String nativeMetadataFormatClassName = "ch5.imageio.ch5stream";

  static final String[] extraMetadataFormatNames = null;

  static final String[] extraMetadataFormatClassNames = null;

  static final boolean standardMetadataFormatSupported = false;

  public int numberImages;

  public ch5StreamMetadata() {
    super(standardMetadataFormatSupported, nativeMetadataFormatName,
        nativeMetadataFormatClassName, extraMetadataFormatNames,
        extraMetadataFormatClassNames);
    numberImages = -1;
  }

  public boolean isReadOnly() {
    return true;
  }

  /**
   * IIOMetadataFormat objects are meant to describe the structure of metadata
   * returned from the getAsTree method. In this case, no such description is
   * available
   */
  public IIOMetadataFormat getMetadataFormat(String formatName) {
    if (formatName.equals(nativeMetadataFormatName)) {
      return null;
    else {
      throw new IllegalArgumentException("Unrecognized format!");
    }
  }

  /**
   * returns the stream metadata in a tree corresponding to the provided
   * formatName
   */
  public Node getAsTree(String formatName) {
    if (formatName.equals(nativeMetadataFormatName)) {
      return getNativeTree();
    else {
      throw new IllegalArgumentException("Unrecognized format!");
    }
  }

  /**
   * returns the stream metadata in a tree using the following format
   * <!ELEMENT ch5.imageio.ch5stream_1.00 (imageDimensions)> <!ATTLIST
   * imageDimensions numberImages CDATA #REQUIRED
   */
  private Node getNativeTree() {
    IIOMetadataNode node; // scratch node

    IIOMetadataNode root = new IIOMetadataNode(nativeMetadataFormatName);

    // Image descriptor
    node = new IIOMetadataNode("imageDimensions");
    node.setAttribute("numberImages", Integer.toString(numberImages));
    root.appendChild(node);

    return root;
  }

  public void setFromTree(String formatName, Node root) {
    throw new IllegalStateException("Metadata is read-only!");
  }

  public void mergeTree(String formatName, Node root) {
    throw new IllegalStateException("Metadata is read-only!");
  }

  public void reset() {
    throw new IllegalStateException("Metadata is read-only!");
  }

  /**
   * initialize the stream metadata element numberImages
   */
  public void initialize(int numberImages) {
    this.numberImages = numberImages;
  }
}

           
         
    
  
Related examples in the same category
1. 显示ImageIO支持的图像
2. 打印图像直接打印
3. 列出所有读和写格式支持ImageIO
4. 显示可用ImageReaders和ImageWriters的图像格式和MIME类型显示可用ImageReaders和ImageWriters的图像格式和MIME类型
5. Write an image of a given format
6. Read an image
7. Simple, functional ImageReaderSpi used to understand how information
8. Example showing how to reset the ordering of ImageReaderSpis in Image I/OExample showing how to reset the ordering of ImageReaderSpis in Image I/O
9. 使用mediatracker预先加载图片
10. Get list of unique supported read formats
11. Get list of unique supported write formats
12. Get list of unique MIME types that can be read
13. Get list of unique MIME types that can be written
14. 返回true如果指定的格式名称可以读取
15. 返回true如果指定格式的名称可以是可写
16. 返回true如果指定的文件扩展名可以读取
17. 返回true如果指定的文件扩展名可以写
18. 返回true如果指定的MIME类型可以读取
19. 返回true如果指定的MIME类型可以写
20. 查看ImageIO信息
21. 查看图像不同类型
22. 加载图像文件从一个文件夹或JAR文件:使用javax.imageio.ImageIO级阅读图像文件
www.java2java.com | Contact Us
Copyright 2010 - 2030 Java Source and Support. All rights reserved.
All other trademarks are property of their respective owners.