zoukankan      html  css  js  c++  java
  • READING, MODIFYING, AND SAVING IMAGES

    By Julian Robichaux,
    SNAPPS






    This month's developer article talks about how to manipulate image files
    (like JPG or PNG files) with your code. While there are a number of third-party
    DLLs and applications you might tap into for this purpose, you'll probably find
    that you can do most, if not all, of the things you want to do using Java right
    out of the box.


    Reading Images
    The built-in Java
    library for reading and writing images is the ImageIO library. This was
    available as an extra library in early versions of Java (you could download it
    from Sun and add it to your classpath), and it has been a part of the standard
    Java distribution since Java 1.4. That's Lotus Notes 7.0 and higher to you and
    me.


    As Java versions have been updated with newer
    versions of the Notes client, we have also gained some additional functionality
    with the built-in ImageIO framework with newer versions of the client.
    Specifically, here are the image types we can read in Notes 7 and higher:



    • Notes 7: JPG and PNG
    • Notes 8: JPG, PNG, BMP, and GIF
    • Notes 8.5: JPG, PNG, BMP, and GIF

    An interesting thing to keep in mind is that while Notes 8 can read GIF files, support for writing GIF files (as we'll see later) is not
    available by default until Notes 8.5. Also, the ImageIO framework has an API for
    plugins, so there are additional plugins available that you can use to read
    and/or write other image formats.


    I've also found that certain types of PNG files are not able to be read
    properly by the base Java ImageIO class. See this page for one instance and a little explanation. As with
    the use of additional file types, you might find that you have to use other
    libraries or plugins (like javapng from Google)
    to get full PNG support.


    Reading a file for manipulation as a BufferedImage is as easy as writing a few lines of code
    like this:


       FileInputStream fis = new FileInputStream(fileName);
       BufferedImage bi = ImageIO.read(fis);
    

    From there, you can modify the BufferedImage to
    make any alterations to the image before resaving it.


    Modifying Images
    Modifying an image
    involves making modifications to the in-memory BufferedImage that we now have access to. There are two
    primary ways in which we will modify an image: redrawing the image and filtering
    the image.


    Redrawing an image (cropping it, rotating it,
    adjusting its size) can be done by using the Graphics2D object to create a new
    "canvas" to redraw the BufferedImage onto it, thereby creating a new
    BufferedImage at the desired size, rotation, or position. For example, here's
    how to resize an image:


       BufferedImage bi2 = new BufferedImage(width, height, bi.getType());
       Graphics2D g2 = bi2.createGraphics();
       g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
       g2.drawImage(bi, 0, 0, width, height, null);
       g2.dispose();
       return bi2;
    

    You can call g2.rotate() before the call to g2.drawImage() if you want to rotate the image, and you
    can actually crop the image by calling BufferedImage.getSubimage() to create a new cropped BufferedImage.


    You can actually use AffineTransforms (which we'll discuss in the next
    paragraph) to do the image scaling or rotation as well. However, you have much
    better control over the quality of the resulting image if you use Graphics2D
    methods directly for this functionality. For a good workaround for the problem
    of poor image quality when you create image thumbnails, see Chris Campbell's
    article "The Perils of Image.getScaledInstance()".


    Pretty much any other kind of image manipulation
    you want to do — like adjusting colors and contrast, blurring, sharpening, etc.
    — requires the use of a Java 2D BufferedImageOp filter. Some of the ones you'll
    find useful are:



    • AffineTransformOp for
      scaling, flipping, or rotating (although as mentioned above, you might get
      better results for scaling and rotating by using Graphics2D directly)
    • ColorConvertOp for
      adjusting image colors or converting to greyscale
    • RescaleOp for
      adjusting contrast and brightness
    • ConvolveOp for
      blurring, sharpening, or edge-detection

    Here's an example of creating a greyscale version
    of an image:


       ColorConvertOp op = new ColorConvertOp(
          ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
       return op.filter(bi, null);
    

    None of these operations will directly modify the BufferedImage that they operate on; rather, they do their
    work and return a new instance of a BufferedImage
    that you must now retain in memory.


    Saving
    Images

    The ImageIO class again comes into
    play when we save the BufferedImage that we've
    modified. We just have to make a call to ImageIO.write() to save the in-memory image to a file. For
    example:


       String fileName = "c:\\myNewFile.png";
       ImageIO.write(bi, "png", new File(fileName));
    

    As with the file types that can be read, the file
    types that we can generate are different for different versions of Lotus
    Notes:



    • Notes 7: JPG and PNG
    • Notes 8: JPG, PNG, and BMP
    • Notes 8.5: JPG, PNG, BMP, and GIF

    Even if you don't make any changes to the image
    file at all, you can use the ImageIO class to
    convert from one file type to another. One limitation that I've run into is that
    the JPG output quality is often pretty poor. I don't know why that is, but a
    workaround I've found is to use code like this for generating JPG output:


       Iterator iter = ImageIO.getImageWritersByFormatName("jpeg");
       ImageWriter writer = (ImageWriter)iter.next();
       ImageWriteParam iwp = writer.getDefaultWriteParam();
       iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
       iwp.setCompressionQuality(quality);  // 1f = 100%, 0.9f = 90%, etc.
    	
       File file = new File(fileName);
       FileImageOutputStream out = new FileImageOutputStream(file);
       writer.setOutput(out);
       IIOImage image = new IIOImage(bi, null, null);
       writer.write(null, image, iwp);
    	
       out.close();
       writer.dispose();
    

    As I mentioned in the "Reading Images" section, there are plugins and
    additional libraries available that can be used to generate other image types
    too.


    What About LotusScript?
    If you're a
    LotusScript programmer, you can still take advantage of all this built-in
    functionality directly through your LotusScript code. Just use LS2J. In fact, an
    example of using many of the techniques I've talked about above as well as an
    LS2J wrapper to make calls to an image manipulation Java library is available on
    my
    Web site.


    Limitations
    The primary (and
    obvious) limitation is the small number of file types that you are limited to.
    However, that's just an "out of the box" limitation that you can use plugins and
    other libraries to work around. Ask Google for help.


    If you're doing a large amount of image processing (or working on very large
    images), make sure you don't hold too many BufferedImages in memory.


    Also, because you will almost certainly be dealing with the local file system
    (reading files, writing files, or both), make sure that any server-based agents
    that use these techniques have the security set to "Allow restricted operations"
    and the agent signer is allowed to run unrestricted operations on the
    server.


    BONUS:
    Embedding images into rich text fields

    As a related topic, see my
    December 2008 Clippings article "Four Things You Thought You Couldn't Do With Rich Text" to get
    some information on how you can embed an image file directly into a rich text
    field — as a real image, not just an attachment.

  • 相关阅读:
    【软件工程】Alpha冲刺 (6/6)
    【软件工程】Alpha冲刺 (5/6)
    为什么三层感知器能够解决任意区域组合的分类问题(不同隐层数的感知器的分类能力)
    PCA学习笔记(含推导过程)
    软件工程实践总结
    Beta冲刺(2/5)(麻瓜制造者)
    Beta冲刺(1/5)(麻瓜制造者)
    个人作业——华为软件开发云案例分析
    Alpha- 事后诸葛亮(麻瓜制造者)
    Alpha课堂展示(麻瓜制造者)
  • 原文地址:https://www.cnblogs.com/hannover/p/2466761.html
Copyright © 2011-2022 走看看