1/* 2 * Copyright (C) 2014 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 */ 16package android.uirendering.cts.testclasses; 17 18import android.graphics.Bitmap; 19import android.graphics.Color; 20import android.graphics.Paint; 21import android.graphics.PaintFlagsDrawFilter; 22import android.support.test.filters.MediumTest; 23import android.support.test.runner.AndroidJUnit4; 24import android.uirendering.cts.bitmapverifiers.BitmapVerifier; 25import android.uirendering.cts.bitmapverifiers.ColorVerifier; 26import android.uirendering.cts.bitmapverifiers.PerPixelBitmapVerifier; 27import android.uirendering.cts.testinfrastructure.ActivityTestBase; 28import android.uirendering.cts.testinfrastructure.CanvasClient; 29 30import org.junit.Test; 31import org.junit.runner.RunWith; 32 33@MediumTest 34@RunWith(AndroidJUnit4.class) 35public class BitmapFilterTests extends ActivityTestBase { 36 private static final int WHITE_WEIGHT = 255 * 3; 37 private enum FilterEnum { 38 // Creates Paint object that will have bitmap filtering 39 PAINT_FILTER, 40 // First uses a Paint object with bitmap filtering, then uses canvas.setDrawFilter to remove 41 // the bitmap filtering 42 REMOVE_FILTER, 43 // Sets DrawFilter to use Paint.FILTER_BITMAP_FLAG 44 ADD_FILTER 45 } 46 47 private static final BitmapVerifier BLACK_WHITE_ONLY_VERIFIER 48 = new PerPixelBitmapVerifier(PerPixelBitmapVerifier.DEFAULT_THRESHOLD, 0.99f) { 49 @Override 50 protected boolean verifyPixel(int x, int y, int color) { 51 int weight = Color.red(color) + Color.blue(color) + Color.green(color); 52 return weight < DEFAULT_THRESHOLD // is approx Color.BLACK 53 || weight > WHITE_WEIGHT - DEFAULT_THRESHOLD; // is approx Color.WHITE 54 } 55 }; 56 private static final BitmapVerifier GREY_ONLY_VERIFIER 57 = new ColorVerifier(Color.argb(255, 127, 127, 127), 58 150); // content will be entirely grey, for a fairly wide range of grey 59 private static final BitmapVerifier GREY_PARTIAL_VERIFIER 60 = new ColorVerifier(Color.argb(255, 127, 127, 127), 61 300, 0.8f); // content will be mostly grey, for a wide range of grey 62 63 64 private static Bitmap createGridBitmap(int width, int height) { 65 Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 66 for (int i = 0 ; i < width ; i++) { 67 for (int j = 0 ; j < height ; j++) { 68 boolean isWhite = (i + j * width) % 2 == 0; 69 bitmap.setPixel(i, j, isWhite ? Color.WHITE : Color.BLACK); 70 } 71 } 72 return bitmap; 73 } 74 75 private static final int SMALL_GRID_SIZE = 5; 76 private Bitmap mSmallGridBitmap = createGridBitmap(SMALL_GRID_SIZE, SMALL_GRID_SIZE); 77 78 // samples will occur in the middle of 4 pixels, 2 white 79 // and 2 black, and thus each be close to x7F7F7F grey 80 private static final int BIG_GRID_SIZE = TEST_WIDTH * 2; 81 private Bitmap mBigGridBitmap = createGridBitmap(BIG_GRID_SIZE, BIG_GRID_SIZE); 82 83 @Test 84 public void testPaintFilterScaleUp() { 85 runScaleTest(FilterEnum.PAINT_FILTER, true); 86 } 87 88 @Test 89 public void testPaintFilterScaleDown() { 90 runScaleTest(FilterEnum.PAINT_FILTER, false); 91 } 92 93 @Test 94 public void testDrawFilterRemoveFilterScaleUp() { 95 runScaleTest(FilterEnum.REMOVE_FILTER, true); 96 } 97 98 @Test 99 public void testDrawFilterRemoveFilterScaleDown() { 100 runScaleTest(FilterEnum.REMOVE_FILTER, false); 101 } 102 103 @Test 104 public void testDrawFilterScaleUp() { 105 runScaleTest(FilterEnum.ADD_FILTER, true); 106 } 107 108 @Test 109 public void testDrawFilterScaleDown() { 110 runScaleTest(FilterEnum.ADD_FILTER, false); 111 } 112 113 private void runScaleTest(final FilterEnum filterEnum, final boolean scaleUp) { 114 final int gridWidth = scaleUp ? SMALL_GRID_SIZE : BIG_GRID_SIZE; 115 final Paint paint = new Paint(filterEnum.equals(FilterEnum.ADD_FILTER) ? 116 0 : Paint.FILTER_BITMAP_FLAG); 117 118 CanvasClient canvasClient = (canvas, width, height) -> { 119 canvas.scale(1.0f * width / gridWidth, 1.0f * height / gridWidth); 120 if (filterEnum.equals(FilterEnum.ADD_FILTER)) { 121 canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG)); 122 } else if (filterEnum.equals(FilterEnum.REMOVE_FILTER)) { 123 canvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0)); 124 } 125 canvas.drawBitmap(scaleUp ? mSmallGridBitmap : mBigGridBitmap, 0, 0, paint); 126 canvas.setDrawFilter(null); 127 }; 128 createTest() 129 // Picture does not support PaintFlagsDrawFilter 130 .addCanvasClientWithoutUsingPicture(canvasClient) 131 .runWithVerifier(getVerifierForTest(filterEnum, scaleUp)); 132 } 133 134 private static BitmapVerifier getVerifierForTest(FilterEnum filterEnum, boolean scaleUp) { 135 if (filterEnum.equals(FilterEnum.REMOVE_FILTER)) { 136 // filtering disabled, so only black and white pixels will come through 137 return BLACK_WHITE_ONLY_VERIFIER; 138 } 139 // if scaling up, output pixels may have single source to sample from, 140 // will only be *mostly* grey. 141 return scaleUp ? GREY_PARTIAL_VERIFIER : GREY_ONLY_VERIFIER; 142 } 143} 144