1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 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 17package android.uirendering.cts.testclasses; 18 19import static org.junit.Assert.assertEquals; 20import static org.junit.Assert.assertNotNull; 21import static org.junit.Assert.assertNull; 22import static org.junit.Assert.assertTrue; 23 24import android.content.res.Resources; 25import android.graphics.BitmapRegionDecoder; 26import android.graphics.Color; 27import android.graphics.Matrix; 28import android.graphics.Paint; 29import android.graphics.Rect; 30import android.graphics.drawable.Drawable; 31import android.graphics.drawable.NinePatchDrawable; 32import android.support.test.runner.AndroidJUnit4; 33import android.uirendering.cts.R; 34 35import android.graphics.Bitmap; 36import android.graphics.BitmapFactory; 37import android.support.test.filters.MediumTest; 38import android.uirendering.cts.bitmapcomparers.ExactComparer; 39import android.uirendering.cts.bitmapcomparers.MSSIMComparer; 40import android.uirendering.cts.bitmapverifiers.GoldenImageVerifier; 41import android.uirendering.cts.testinfrastructure.ActivityTestBase; 42import android.util.DisplayMetrics; 43 44import org.junit.Before; 45import org.junit.Test; 46import org.junit.runner.RunWith; 47 48import java.io.ByteArrayInputStream; 49import java.io.ByteArrayOutputStream; 50import java.io.IOException; 51import java.io.InputStream; 52 53@MediumTest 54@RunWith(AndroidJUnit4.class) 55public class HardwareBitmapTests extends ActivityTestBase { 56 57 private Resources mRes; 58 59 private static final BitmapFactory.Options HARDWARE_OPTIONS = createHardwareOptions(); 60 61 private static BitmapFactory.Options createHardwareOptions() { 62 BitmapFactory.Options options = new BitmapFactory.Options(); 63 options.inPreferredConfig = Bitmap.Config.HARDWARE; 64 return options; 65 } 66 67 @Before 68 public void setup() { 69 mRes = getActivity().getResources(); 70 } 71 72 @Test 73 public void testDecodeResource() { 74 createTest().addCanvasClientWithoutUsingPicture((canvas, width, height) -> { 75 Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot, 76 HARDWARE_OPTIONS); 77 canvas.drawBitmap(hardwareBitmap, 0, 0, new Paint()); 78 }, true).runWithVerifier(new GoldenImageVerifier(getActivity(), 79 R.drawable.golden_robot, new MSSIMComparer(0.95))); 80 } 81 82 @Test 83 public void testBitmapRegionDecode() throws IOException { 84 InputStream inputStream = mRes.openRawResource(R.drawable.robot); 85 BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(inputStream, false); 86 createTest().addCanvasClientWithoutUsingPicture((canvas, width, height) -> { 87 Bitmap hardwareBitmap = decoder.decodeRegion(new Rect(10, 15, 34, 39), 88 HARDWARE_OPTIONS); 89 canvas.drawBitmap(hardwareBitmap, 0, 0, new Paint()); 90 }, true).runWithVerifier(new GoldenImageVerifier(getActivity(), 91 R.drawable.golden_headless_robot, new MSSIMComparer(0.95))); 92 } 93 94 @Test 95 public void testBitmapConfigFromRGB565() { 96 testBitmapCopy(R.drawable.robot, Bitmap.Config.RGB_565, Bitmap.Config.HARDWARE); 97 } 98 99 @Test 100 public void testBitmapConfigFromARGB8888() { 101 testBitmapCopy(R.drawable.robot, Bitmap.Config.ARGB_8888, Bitmap.Config.HARDWARE); 102 } 103 104 @Test 105 public void testBitmapConfigFromA8() { 106 Bitmap b = Bitmap.createBitmap(32, 32, Bitmap.Config.ALPHA_8); 107 // we do not support conversion from A8 108 assertNull(b.copy(Bitmap.Config.HARDWARE, false)); 109 } 110 111 @Test 112 public void testBitmapConfigFromIndex8() { 113 testBitmapCopy(R.drawable.index_8, null, Bitmap.Config.HARDWARE); 114 } 115 116 @Test 117 public void testBitmapConfigFromHardwareToHardware() { 118 testBitmapCopy(R.drawable.robot, Bitmap.Config.HARDWARE, Bitmap.Config.HARDWARE); 119 } 120 121 @Test 122 public void testBitmapConfigFromHardwareToARGB8888() { 123 testBitmapCopy(R.drawable.robot, Bitmap.Config.HARDWARE, Bitmap.Config.ARGB_8888); 124 } 125 126 @Test 127 public void testSetDensity() { 128 createTest().addCanvasClientWithoutUsingPicture((canvas, width, height) -> { 129 Bitmap bitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot); 130 bitmap.setDensity(DisplayMetrics.DENSITY_LOW); 131 canvas.drawBitmap(bitmap, 0, 0, null); 132 }, true).addCanvasClientWithoutUsingPicture((canvas, width, height) -> { 133 Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot, 134 HARDWARE_OPTIONS); 135 hardwareBitmap.setDensity(DisplayMetrics.DENSITY_LOW); 136 canvas.drawBitmap(hardwareBitmap, 0, 0, null); 137 }, true).runWithComparer(new ExactComparer()); 138 } 139 140 @Test 141 public void testNinePatch() { 142 createTest().addCanvasClientWithoutUsingPicture((canvas, width, height) -> { 143 InputStream is = mRes.openRawResource(R.drawable.blue_padded_square); 144 NinePatchDrawable ninePatch = (NinePatchDrawable) Drawable.createFromResourceStream( 145 mRes, null, is, null, HARDWARE_OPTIONS); 146 ninePatch.setBounds(0, 0, width, height); 147 ninePatch.draw(canvas); 148 }, true).runWithVerifier(new GoldenImageVerifier(getActivity(), 149 R.drawable.golden_hardwaretest_ninepatch, new MSSIMComparer(0.95))); 150 } 151 152 @Test 153 public void testCreateIdentityBitmap() { 154 Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot, 155 HARDWARE_OPTIONS); 156 Bitmap newBitmap = Bitmap.createBitmap(hardwareBitmap); 157 assertEquals(hardwareBitmap, newBitmap); 158 } 159 160 @Test 161 public void testCreateScaledBitmap() { 162 createTest().addCanvasClientWithoutUsingPicture((canvas, width, height) -> { 163 Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot, 164 HARDWARE_OPTIONS); 165 Bitmap scaled = Bitmap.createScaledBitmap(hardwareBitmap, 24, 24, false); 166 assertEquals(Bitmap.Config.HARDWARE, scaled.getConfig()); 167 canvas.drawBitmap(scaled, 0, 0, null); 168 }, true).runWithVerifier(new GoldenImageVerifier(getActivity(), 169 R.drawable.golden_hardwaretest_create_scaled, new MSSIMComparer(0.9))); 170 } 171 172 @Test 173 public void testCreateSubsetBitmap() { 174 createTest().addCanvasClientWithoutUsingPicture((canvas, width, height) -> { 175 Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot, 176 HARDWARE_OPTIONS); 177 Matrix matrix = new Matrix(); 178 matrix.setRotate(90); 179 Bitmap cropped = Bitmap.createBitmap(hardwareBitmap, 7, 7, 30, 30); 180 assertEquals(Bitmap.Config.HARDWARE, cropped.getConfig()); 181 canvas.drawBitmap(cropped, 0, 0, null); 182 }, true).runWithVerifier(new GoldenImageVerifier(getActivity(), 183 R.drawable.golden_hardwaretest_create_subset, new MSSIMComparer(0.9))); 184 } 185 186 @Test 187 public void testCreateTransformedBitmap() { 188 createTest().addCanvasClientWithoutUsingPicture((canvas, width, height) -> { 189 Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot, 190 HARDWARE_OPTIONS); 191 Matrix matrix = new Matrix(); 192 matrix.setRotate(90); 193 Bitmap transformed = Bitmap.createBitmap(hardwareBitmap, 7, 7, 30, 30, matrix, false); 194 assertEquals(Bitmap.Config.HARDWARE, transformed.getConfig()); 195 canvas.drawBitmap(transformed, 0, 0, null); 196 }, true).runWithVerifier(new GoldenImageVerifier(getActivity(), 197 R.drawable.golden_hardwaretest_create_transformed, new MSSIMComparer(0.9))); 198 } 199 200 201 @Test 202 public void testCompressHardware() { 203 Bitmap hardwareBitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot, 204 HARDWARE_OPTIONS); 205 ByteArrayOutputStream stream = new ByteArrayOutputStream(); 206 assertTrue(hardwareBitmap.compress(Bitmap.CompressFormat.PNG, 50, stream)); 207 Bitmap decoded = BitmapFactory.decodeStream( 208 new ByteArrayInputStream(stream.toByteArray())); 209 createTest().addCanvasClientWithoutUsingPicture((canvas, width, height) -> { 210 canvas.drawColor(Color.CYAN); 211 canvas.drawBitmap(hardwareBitmap, 0, 0, null); 212 }, true).addCanvasClientWithoutUsingPicture((canvas, width, height) -> { 213 canvas.drawColor(Color.CYAN); 214 canvas.drawBitmap(decoded, 0, 0, null); 215 }, true).runWithComparer(new MSSIMComparer(0.99)); 216 217 } 218 219 @Test 220 public void testHardwareExtractAlpha() { 221 Bitmap bitmap = Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888); 222 bitmap.eraseColor(Color.argb(127, 250, 0, 0)); 223 bitmap.setPixel(25, 25, Color.BLUE); 224 225 Bitmap hwBitmap = bitmap.copy(Bitmap.Config.HARDWARE, false); 226 Bitmap alphaBitmap = hwBitmap.extractAlpha(); 227 assertEquals(Bitmap.Config.ALPHA_8, alphaBitmap.getConfig()); 228 assertTrue(Color.alpha(alphaBitmap.getPixel(25, 25)) >= 254); 229 assertEquals(127, Color.alpha(alphaBitmap.getPixel(40, 40))); 230 } 231 232 private void testBitmapCopy(int id, Bitmap.Config from, Bitmap.Config to) { 233 BitmapFactory.Options options = new BitmapFactory.Options(); 234 options.inScaled = false; 235 options.inPreferredConfig = from; 236 Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(), id, options); 237 assertEquals(from, bitmap.getConfig()); 238 239 createTest().addCanvasClientWithoutUsingPicture((canvas, width, height) -> { 240 canvas.drawColor(Color.CYAN); 241 canvas.drawBitmap(bitmap, 0, 0, null); 242 }, true).addCanvasClientWithoutUsingPicture((canvas, width, height) -> { 243 canvas.drawColor(Color.CYAN); 244 Bitmap copy = bitmap.copy(to, false); 245 assertNotNull(copy); 246 assertEquals(to, copy.getConfig()); 247 canvas.drawBitmap(copy, 0, 0, null); 248 }, true).runWithComparer(new MSSIMComparer(0.99)); 249 } 250}