1 /* 2 * Copyright 2022 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 17 package platform.test.screenshot.matchers 18 19 import android.graphics.Bitmap 20 import android.graphics.Color 21 import android.graphics.Rect 22 import kotlin.collections.List 23 import platform.test.screenshot.proto.ScreenshotResultProto 24 25 /** 26 * Bitmap matching that does an exact comparison of pixels between bitmaps. 27 */ 28 class PixelPerfectMatcher : BitmapMatcher() { 29 compareBitmapsnull30 override fun compareBitmaps( 31 expected: IntArray, 32 given: IntArray, 33 width: Int, 34 height: Int, 35 regions: List<Rect> 36 ): MatchResult { 37 check(expected.size == given.size) 38 39 val filter = getFilter(width, height, regions) 40 var different = 0 41 var same = 0 42 var ignored = 0 43 44 val diffArray = IntArray(width * height) 45 46 for (x in 0 until width) { 47 for (y in 0 until height) { 48 val index = x + y * width 49 if (filter[index] == 0) { 50 ignored++ 51 continue 52 } 53 val referenceColor = expected[index] 54 val testColor = given[index] 55 if (referenceColor == testColor) { 56 ++same 57 } else { 58 ++different 59 } 60 diffArray[index] = 61 diffColor( 62 referenceColor, 63 testColor 64 ) 65 } 66 } 67 68 val stats = ScreenshotResultProto.DiffResult.ComparisonStatistics 69 .newBuilder() 70 .setNumberPixelsCompared(width * height) 71 .setNumberPixelsIdentical(same) 72 .setNumberPixelsDifferent(different) 73 .setNumberPixelsIgnored(ignored) 74 .build() 75 76 if (different > 0) { 77 val diff = Bitmap.createBitmap(diffArray, width, height, Bitmap.Config.ARGB_8888) 78 return MatchResult(matches = false, diff = diff, comparisonStatistics = stats) 79 } 80 return MatchResult(matches = true, diff = null, comparisonStatistics = stats) 81 } 82 diffColornull83 private fun diffColor(referenceColor: Int, testColor: Int): Int { 84 return if (referenceColor != testColor) { 85 Color.MAGENTA 86 } else { 87 Color.TRANSPARENT 88 } 89 } 90 } 91