Home | History | Annotate | Download | only in gle2
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.eclipse.org/org/documents/epl-v10.php
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.ide.eclipse.adt.internal.editors.layout.gle2;
     17 
     18 import com.android.ide.common.api.Rect;
     19 
     20 import org.eclipse.swt.graphics.RGB;
     21 import org.eclipse.swt.graphics.Rectangle;
     22 
     23 import java.awt.Color;
     24 import java.awt.Graphics;
     25 import java.awt.Graphics2D;
     26 import java.awt.image.BufferedImage;
     27 import java.util.Arrays;
     28 import java.util.Collections;
     29 import java.util.List;
     30 
     31 import junit.framework.TestCase;
     32 
     33 @SuppressWarnings("javadoc")
     34 public class ImageUtilsTest extends TestCase {
     35     public void testCropBlank() throws Exception {
     36         BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE);
     37         Graphics g = image.getGraphics();
     38         g.setColor(new Color(0, true));
     39         g.fillRect(0, 0, image.getWidth(), image.getHeight());
     40         g.dispose();
     41 
     42         BufferedImage crop = ImageUtils.cropBlank(image, null);
     43         assertNull(crop);
     44     }
     45 
     46     public void testCropBlankPre() throws Exception {
     47         BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE);
     48         Graphics g = image.getGraphics();
     49         g.setColor(new Color(0, true));
     50         g.fillRect(0, 0, image.getWidth(), image.getHeight());
     51         g.dispose();
     52 
     53         BufferedImage crop = ImageUtils.cropBlank(image, new Rect(5, 5, 80, 80));
     54         assertNull(crop);
     55     }
     56 
     57     public void testCropNonblank() throws Exception {
     58         BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE);
     59         Graphics g = image.getGraphics();
     60         g.setColor(new Color(0, false));
     61         g.fillRect(0, 0, image.getWidth(), image.getHeight());
     62         g.dispose();
     63 
     64         BufferedImage crop = ImageUtils.cropBlank(image, null);
     65         assertNotNull(crop);
     66         assertEquals(image.getWidth(), crop.getWidth());
     67         assertEquals(image.getHeight(), crop.getHeight());
     68     }
     69 
     70     public void testCropSomething() throws Exception {
     71         BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE);
     72         Graphics g = image.getGraphics();
     73         g.setColor(new Color(0, true));
     74         g.fillRect(0, 0, image.getWidth(), image.getHeight());
     75         g.setColor(new Color(0xFF00FF00, true));
     76         g.fillRect(25, 25, 50, 50);
     77         g.dispose();
     78 
     79         BufferedImage crop = ImageUtils.cropBlank(image, null);
     80         assertNotNull(crop);
     81         assertEquals(50, crop.getWidth());
     82         assertEquals(50, crop.getHeight());
     83         assertEquals(0xFF00FF00, crop.getRGB(0, 0));
     84         assertEquals(0xFF00FF00, crop.getRGB(49, 49));
     85     }
     86 
     87     public void testCropSomethingPre() throws Exception {
     88         BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE);
     89         Graphics g = image.getGraphics();
     90         g.setColor(new Color(0, true));
     91         g.fillRect(0, 0, image.getWidth(), image.getHeight());
     92         g.setColor(new Color(0xFF00FF00, true));
     93         g.fillRect(25, 25, 50, 50);
     94         g.dispose();
     95 
     96         BufferedImage crop = ImageUtils.cropBlank(image, new Rect(0, 0, 100, 100));
     97         assertNotNull(crop);
     98         assertEquals(50, crop.getWidth());
     99         assertEquals(50, crop.getHeight());
    100         assertEquals(0xFF00FF00, crop.getRGB(0, 0));
    101         assertEquals(0xFF00FF00, crop.getRGB(49, 49));
    102     }
    103 
    104     public void testCropSomethingPre2() throws Exception {
    105         BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE);
    106         Graphics g = image.getGraphics();
    107         g.setColor(new Color(0, true));
    108         g.fillRect(0, 0, image.getWidth(), image.getHeight());
    109         g.setColor(new Color(0xFF00FF00, true));
    110         g.fillRect(25, 25, 50, 50);
    111         g.dispose();
    112 
    113         BufferedImage crop = ImageUtils.cropBlank(image, new Rect(5, 5, 80, 80));
    114         assertNotNull(crop);
    115         assertEquals(50, crop.getWidth());
    116         assertEquals(50, crop.getHeight());
    117         assertEquals(0xFF00FF00, crop.getRGB(0, 0));
    118         assertEquals(0xFF00FF00, crop.getRGB(49, 49));
    119     }
    120 
    121     public void testCropColor() throws Exception {
    122         BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE);
    123         Graphics g = image.getGraphics();
    124         g.setColor(new Color(0xFF00FF00, true));
    125         g.fillRect(0, 0, image.getWidth(), image.getHeight());
    126         g.dispose();
    127 
    128         BufferedImage crop = ImageUtils.cropColor(image, 0xFF00FF00, null);
    129         assertNull(crop);
    130     }
    131 
    132     public void testCropNonColor() throws Exception {
    133         BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE);
    134         Graphics g = image.getGraphics();
    135         g.setColor(new Color(0xFF00FF00, true));
    136         g.fillRect(0, 0, image.getWidth(), image.getHeight());
    137         g.dispose();
    138 
    139         BufferedImage crop = ImageUtils.cropColor(image, 0xFFFF0000, null);
    140         assertNotNull(crop);
    141         assertEquals(image.getWidth(), crop.getWidth());
    142         assertEquals(image.getHeight(), crop.getHeight());
    143     }
    144 
    145     public void testCropColorSomething() throws Exception {
    146         BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE);
    147         Graphics g = image.getGraphics();
    148         g.setColor(new Color(0xFF00FF00, true));
    149         g.fillRect(0, 0, image.getWidth(), image.getHeight());
    150         g.setColor(new Color(0xFFFF0000, true));
    151         g.fillRect(25, 25, 50, 50);
    152         g.dispose();
    153 
    154         BufferedImage crop = ImageUtils.cropColor(image, 0xFF00FF00, null);
    155         assertEquals(50, crop.getWidth());
    156         assertEquals(50, crop.getHeight());
    157         assertEquals(0xFFFF0000, crop.getRGB(0, 0));
    158         assertEquals(0xFFFF0000, crop.getRGB(49, 49));
    159     }
    160 
    161     public void testNothingTodo() throws Exception {
    162         BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE);
    163         Graphics g = image.getGraphics();
    164         g.setColor(new Color(0xFF00FF00, true));
    165         g.fillRect(0, 0, image.getWidth(), image.getHeight());
    166         g.dispose();
    167 
    168         BufferedImage crop = ImageUtils.cropColor(image, 0xFFFF0000, new Rect(40, 40, 0, 0));
    169         assertNull(crop);
    170     }
    171 
    172     public void testContainsDarkPixels() throws Exception {
    173         BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE);
    174         Graphics g = image.getGraphics();
    175         g.setColor(new Color(0, true));
    176         g.fillRect(0, 0, image.getWidth(), image.getHeight());
    177         g.dispose();
    178 
    179         assertFalse(ImageUtils.containsDarkPixels(image));
    180 
    181         image.setRGB(50, 50, 0xFFFFFFFF);
    182         assertFalse(ImageUtils.containsDarkPixels(image));
    183         image.setRGB(50, 50, 0xFFAAAAAA);
    184         assertFalse(ImageUtils.containsDarkPixels(image));
    185         image.setRGB(50, 50, 0xFF00FF00);
    186         assertFalse(ImageUtils.containsDarkPixels(image));
    187         image.setRGB(50, 50, 0xFFFF8800);
    188         assertFalse(ImageUtils.containsDarkPixels(image));
    189         image.setRGB(50, 50, 0xFF333333);
    190         assertTrue(ImageUtils.containsDarkPixels(image));
    191 
    192     }
    193 
    194     public void testGetBoundingRectangle() {
    195         assertEquals(null, ImageUtils.getBoundingRectangle(Collections.<Rectangle> emptyList()));
    196 
    197         assertEquals(new Rectangle(1, 2, 3, 4), ImageUtils.getBoundingRectangle(Arrays
    198                 .asList(new Rectangle(1, 2, 3, 4))));
    199         assertEquals(new Rectangle(1, 2, 3, 4), ImageUtils.getBoundingRectangle(Arrays
    200                 .asList(new Rectangle(1, 2, 3, 4), new Rectangle(1, 2, 1, 1))));
    201         assertEquals(new Rectangle(5, 5, 25, 25), ImageUtils.getBoundingRectangle(Arrays.asList(
    202                 new Rectangle(10, 10, 20, 20), new Rectangle(5, 5, 1, 1))));
    203     }
    204 
    205     /**
    206      * Paints a set of {@link Rectangle} object out of a rendered {@link BufferedImage}
    207      * such that the resulting image is transparent except for a minimum bounding
    208      * rectangle of the selected elements.
    209      *
    210      * @param image the source image
    211      * @param rectangles the set of rectangles to copy
    212      * @param boundingBox the bounding rectangle of the set of rectangles to copy, can be
    213      *            computed by {@link ImageUtils#getBoundingRectangle}
    214      * @param scale a scale factor to apply to the result, e.g. 0.5 to shrink the
    215      *            destination down 50%, 1.0 to leave it alone and 2.0 to zoom in by
    216      *            doubling the image size
    217      * @return a rendered image, or null
    218      */
    219     public static BufferedImage drawRectangles(BufferedImage image,
    220             List<Rectangle> rectangles, Rectangle boundingBox, double scale) {
    221 
    222         // This code is not a test. When I implemented image cropping, I first implemented
    223         // it for BufferedImages (since it's easier; easy image painting, easy scaling,
    224         // easy transparency handling, etc). However, this meant that we would need to
    225         // convert the SWT images from the ImageOverlay to BufferedImages, crop and convert
    226         // back; not ideal, so I rewrote it in SWT (see SwtUtils). However, I
    227         // don't want to throw away the code in case we start keeping BufferedImages rather
    228         // than SWT images or need it for other purposes, but rather than place it in the
    229         // production codebase I'm leaving this utility here in the associated ImageUtils
    230         // test class. It was used like this:
    231         // @formatter:off
    232         //
    233         //    BufferedImage wholeImage = SwtUtils.convertToAwt(image);
    234         //    BufferedImage result = ImageUtils.cropSelection(wholeImage,
    235         //        rectangles, boundingBox, scale);
    236         //    e.image = SwtUtils.convertToSwt(image.getDevice(), result, true,
    237         //        DRAG_TRANSPARENCY);
    238         //
    239         // @formatter:on
    240 
    241         if (boundingBox == null) {
    242             return null;
    243         }
    244 
    245         int destWidth = (int) (scale * boundingBox.width);
    246         int destHeight = (int) (scale * boundingBox.height);
    247         BufferedImage dest = new BufferedImage(destWidth, destHeight, image.getType());
    248 
    249         Graphics2D g = dest.createGraphics();
    250 
    251         for (Rectangle bounds : rectangles) {
    252             int dx1 = bounds.x - boundingBox.x;
    253             int dy1 = bounds.y - boundingBox.y;
    254             int dx2 = dx1 + bounds.width;
    255             int dy2 = dy1 + bounds.height;
    256 
    257             dx1 *= scale;
    258             dy1 *= scale;
    259             dx2 *= scale;
    260             dy2 *= scale;
    261 
    262             int sx1 = bounds.x;
    263             int sy1 = bounds.y;
    264             int sx2 = sx1 + bounds.width;
    265             int sy2 = sy1 + bounds.height;
    266 
    267             g.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
    268         }
    269 
    270         g.dispose();
    271 
    272         return dest;
    273     }
    274 
    275     public void testSubImage() throws Exception {
    276         BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE);
    277         Graphics g = image.getGraphics();
    278         g.setColor(new Color(0xFF00FF00, true));
    279         g.fillRect(0, 0, image.getWidth(), image.getHeight());
    280         g.setColor(new Color(0xFFFF0000, true));
    281         g.fillRect(25, 25, 50, 50);
    282         g.dispose();
    283 
    284         BufferedImage sub = ImageUtils.subImage(image, 25, 25, 35, 45);
    285         assertEquals(10, sub.getWidth());
    286         assertEquals(20, sub.getHeight());
    287         assertEquals(0xFFFF0000, sub.getRGB(0, 0));
    288         assertEquals(0xFFFF0000, sub.getRGB(9, 9));
    289 
    290         sub = ImageUtils.subImage(image, 23, 23, 23 + 5, 23 + 5);
    291         assertEquals(5, sub.getWidth());
    292         assertEquals(5, sub.getHeight());
    293         assertEquals(0xFF00FF00, sub.getRGB(0, 0));
    294         assertEquals(0xFFFF0000, sub.getRGB(4, 4));
    295     }
    296 
    297     public void testGetColor() throws Exception {
    298         assertEquals(0xFF000000, ImageUtils.getColor("#000"));
    299         assertEquals(0xFF000000, ImageUtils.getColor("#000000"));
    300         assertEquals(0xABCDEF91, ImageUtils.getColor("#ABCDEF91"));
    301     }
    302 
    303     public void testGetBrightness() throws Exception {
    304         assertEquals(96, ImageUtils.getBrightness(0x456789));
    305         assertEquals(198, ImageUtils.getBrightness(0xABCDEF));
    306 
    307         assertEquals(0, ImageUtils.getBrightness(0x0));
    308         assertEquals(255, ImageUtils.getBrightness(0xFFFFFF));
    309         assertEquals(299*255/1000, ImageUtils.getBrightness(0xFF0000));
    310         assertEquals(587*255/1000, ImageUtils.getBrightness(0x00FF00));
    311         assertEquals(114*255/1000, ImageUtils.getBrightness(0x0000FF));
    312     }
    313 
    314     public void testColorConversion() throws Exception {
    315         assertEquals(0, ImageUtils.rgbToInt(ImageUtils.intToRgb(0), 0));
    316         assertEquals(0xFFFFFFFF, ImageUtils.rgbToInt(ImageUtils.intToRgb(0xFFFFFF), 0xFF));
    317         assertEquals(0x12345678, ImageUtils.rgbToInt(ImageUtils.intToRgb(0x345678), 0x12));
    318     }
    319 
    320     public void testScaleImage() throws Exception {
    321         BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB_PRE);
    322         Graphics g = image.getGraphics();
    323         g.setColor(new Color(0xFF00FF00, true));
    324         g.fillRect(0, 0, image.getWidth(), image.getHeight());
    325         g.setColor(new Color(0xFFFF0000, true));
    326         g.fillRect(25, 25, 50, 50);
    327         g.dispose();
    328 
    329         BufferedImage scaled = ImageUtils.scale(image, 0.5, 0.5);
    330         assertEquals(50, scaled.getWidth());
    331         assertEquals(50, scaled.getHeight());
    332         assertEquals(0xFF00FF00, scaled.getRGB(0, 0));
    333         assertEquals(0xFF00FF00, scaled.getRGB(49, 49));
    334         assertEquals(0xFFFF0000, scaled.getRGB(25, 25));
    335 
    336         scaled = ImageUtils.scale(image, 2.0, 2.0);
    337         assertEquals(200, scaled.getWidth());
    338         assertEquals(200, scaled.getHeight());
    339         assertEquals(0xFF00FF00, scaled.getRGB(0, 0));
    340         assertEquals(0xFF00FF00, scaled.getRGB(48, 48));
    341         assertEquals(0xFFFF0000, scaled.getRGB(100, 100));
    342         assertEquals(0xFF00FF00, scaled.getRGB(199, 199));
    343 
    344         scaled = ImageUtils.scale(image, 0.25, 0.25);
    345         assertEquals(25, scaled.getWidth());
    346         assertEquals(25, scaled.getHeight());
    347         assertEquals(0xFF00FF00, scaled.getRGB(0, 0));
    348         assertEquals(0xFF00FF00, scaled.getRGB(24, 24));
    349         assertEquals(0xFFFF0000, scaled.getRGB(13, 13));
    350 
    351         scaled = ImageUtils.scale(image, 0.25, 0.25, 75, 95);
    352         assertEquals(100, scaled.getWidth());
    353         assertEquals(120, scaled.getHeight());
    354         assertEquals(0xFF00FF00, scaled.getRGB(0, 0));
    355         assertEquals(0xFF00FF00, scaled.getRGB(24, 24));
    356         assertEquals(0xFFFF0000, scaled.getRGB(13, 13));
    357 
    358     }
    359 
    360     public void testCreateColoredImage() throws Exception {
    361         BufferedImage image = ImageUtils.createColoredImage(120, 110, new RGB(0xFE, 0xFD, 0xFC));
    362         assertEquals(120, image.getWidth());
    363         assertEquals(110, image.getHeight());
    364         assertEquals(0xFFFEFDFC, image.getRGB(0, 0));
    365         assertEquals(0xFFFEFDFC, image.getRGB(50, 50));
    366         assertEquals(0xFFFEFDFC, image.getRGB(119, 109));
    367     }
    368 }
    369