1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug     8139183
  27  * @summary Test verifies whether alpha channel of a translucent
  28  *          image is proper or not after scaling through drawImage.
  29  * @run     main ScaledImageAlphaTest
  30  */
  31 
  32 import java.awt.*;
  33 import java.awt.image.*;
  34 
  35 public class ScaledImageAlphaTest {
  36 
  37     static final int translucentAlpha = 128, opaqueAlpha = 255;
  38     static final int[] translucentVariants = new int[]{
  39         BufferedImage.TYPE_INT_ARGB,
  40         BufferedImage.TYPE_INT_ARGB_PRE,
  41         BufferedImage.TYPE_4BYTE_ABGR,
  42         BufferedImage.TYPE_4BYTE_ABGR_PRE
  43     };
  44     static final int[] alphaValues = new int[]{
  45         translucentAlpha,
  46         opaqueAlpha
  47     };
  48     static int width = 50, height = 50;
  49     static int scaleX = 5, scaleY = 5, scaleWidth = 40, scaleHeight = 40;
  50 
  51     private static void verifyAlpha(Color color, int alpha) {
  52 
  53         /* if extracted alpha value is equal alpha that we set
  54          * for background color, alpha channel is not lost
  55          * while scaling otherwise we have lost alpha channel.
  56          */
  57         int extractedAlpha = color.getAlpha();
  58 
  59         if(extractedAlpha != alpha) {
  60             throw new RuntimeException("Alpha channel for background"
  61                     + " is lost while scaling");
  62         }
  63     }
  64 
  65     private static void validateBufferedImageAlpha() {
  66 
  67         Color backgroundColor, extractedColor;
  68         // verify for all translucent buffered image types
  69         for(int type : translucentVariants) {
  70             // verify for both opaque and translucent background color
  71             for(int alpha : alphaValues) {
  72                 // create BufferedImage of dimension (50,50)
  73                 BufferedImage img = new
  74                     BufferedImage(width, height, type);
  75                 Graphics2D imgGraphics = (Graphics2D)img.getGraphics();
  76                 /* scale image to smaller dimension and set any
  77                  * background color with alpha.
  78                  */
  79                 backgroundColor = new Color(0, 255, 0, alpha);
  80                 imgGraphics.
  81                     drawImage(img, scaleX, scaleY, scaleWidth, scaleHeight,
  82                               backgroundColor, null);
  83                 imgGraphics.dispose();
  84 
  85                 /* get pixel information for background color with
  86                  * scaled coordinates.
  87                  */
  88                 extractedColor = new Color(img.getRGB(scaleX, scaleY), true);
  89                 verifyAlpha(extractedColor, alpha);
  90             }
  91         }
  92     }
  93 
  94     private static void validateVolatileImageAlpha() {
  95 
  96         Color backgroundColor, extractedColor;
  97         VolatileImage img;
  98         BufferedImage bufImg = new
  99                     BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
 100         for(int alpha : alphaValues) {
 101             backgroundColor = new Color(0, 255, 0, alpha);
 102             do {
 103                 img = createVolatileImage(width, height,
 104                                           Transparency.TRANSLUCENT);
 105                 Graphics2D imgGraphics = (Graphics2D)img.getGraphics();
 106                 // clear VolatileImage as by default it has white opaque image
 107                 imgGraphics.setComposite(AlphaComposite.Clear);
 108                 imgGraphics.fillRect(0,0, width, height);
 109 
 110                 imgGraphics.setComposite(AlphaComposite.SrcOver);
 111                 /* scale image to smaller dimension and set background color
 112                  * to green with translucent alpha.
 113                  */
 114                 imgGraphics.
 115                     drawImage(img, scaleX, scaleY, scaleWidth, scaleHeight,
 116                               backgroundColor, null);
 117                 //get BufferedImage out of VolatileImage
 118                 bufImg = img.getSnapshot();
 119                 imgGraphics.dispose();
 120             }while(img.contentsLost());
 121 
 122             /* get pixel information for background color with
 123              * scaled coordinates.
 124              */
 125             extractedColor = new Color(bufImg.getRGB(scaleX, scaleY), true);
 126             verifyAlpha(extractedColor, alpha);
 127         }
 128     }
 129 
 130     private static VolatileImage createVolatileImage(int width, int height,
 131                                                      int transparency) {        
 132         GraphicsEnvironment ge = GraphicsEnvironment.
 133                                  getLocalGraphicsEnvironment();
 134         GraphicsConfiguration gc = ge.getDefaultScreenDevice().
 135                                    getDefaultConfiguration();
 136 
 137         VolatileImage image = gc.createCompatibleVolatileImage(width, height,
 138                                                                transparency);
 139         return image;
 140     }
 141 
 142     public static void main(String[] args) {
 143         // test alpha channel with different types of BufferedImage
 144         validateBufferedImageAlpha();
 145         // test alpha channel with VolatileImage
 146         validateVolatileImageAlpha();
 147     }
 148 }