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  */
16 package android.uirendering.cts.util;
17 
18 import android.graphics.Bitmap;
19 import android.uirendering.cts.differencevisualizers.DifferenceVisualizer;
20 import android.util.Log;
21 
22 import java.io.File;
23 import java.io.FileNotFoundException;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 
27 import libcore.io.IoUtils;
28 
29 /**
30  * A utility class that will allow the user to save bitmaps to the sdcard on the device.
31  */
32 public final class BitmapDumper {
33     private final static String TAG = "BitmapDumper";
34     private final static String IDEAL_RENDERING_FILE_NAME = "idealCapture.png";
35     private final static String TESTED_RENDERING_FILE_NAME = "testedCapture.png";
36     private final static String VISUALIZER_RENDERING_FILE_NAME = "visualizer.png";
37     private final static String SINGULAR_FILE_NAME = "capture.png";
38     private final static String CAPTURE_SUB_DIRECTORY = "/sdcard/UiRenderingCaptures/";
39 
BitmapDumper()40     private BitmapDumper() {}
41 
42     /**
43      * Deletes the specific files for the given test in a given class.
44      */
deleteFileInClassFolder(String className, String testName)45     public static void deleteFileInClassFolder(String className, String testName) {
46         File directory = new File(CAPTURE_SUB_DIRECTORY + className);
47 
48         String[] children = directory.list();
49         if (children == null) {
50             return;
51         }
52         for (String file : children) {
53             if (file.startsWith(testName)) {
54                 new File(directory, file).delete();
55             }
56         }
57     }
58 
createSubDirectory(String className)59     public static void createSubDirectory(String className) {
60         File saveDirectory = new File(CAPTURE_SUB_DIRECTORY + className);
61         if (saveDirectory.exists()) {
62             return;
63         }
64         // Create the directory if it isn't already created.
65         saveDirectory.mkdirs();
66     }
67 
68     /**
69      * Saves two files, one the capture of an ideal drawing, and one the capture of the tested
70      * drawing. The third file saved is a bitmap that is returned from the given visualizer's
71      * method.
72      * The files are saved to the sdcard directory
73      */
dumpBitmaps(Bitmap idealBitmap, Bitmap testedBitmap, String testName, String className, DifferenceVisualizer differenceVisualizer)74     public static void dumpBitmaps(Bitmap idealBitmap, Bitmap testedBitmap, String testName,
75             String className, DifferenceVisualizer differenceVisualizer) {
76         Bitmap visualizerBitmap;
77 
78         int width = idealBitmap.getWidth();
79         int height = idealBitmap.getHeight();
80         int[] testedArray = new int[width * height];
81         int[] idealArray = new int[width * height];
82         idealBitmap.getPixels(testedArray, 0, width, 0, 0, width, height);
83         testedBitmap.getPixels(idealArray, 0, width, 0, 0, width, height);
84         int[] visualizerArray = differenceVisualizer.getDifferences(idealArray, testedArray);
85         visualizerBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
86         visualizerBitmap.setPixels(visualizerArray, 0, width, 0, 0, width, height);
87         Bitmap croppedBitmap = Bitmap.createBitmap(testedBitmap, 0, 0, width, height);
88 
89         saveFile(className, testName, IDEAL_RENDERING_FILE_NAME, idealBitmap);
90         saveFile(className, testName, TESTED_RENDERING_FILE_NAME, croppedBitmap);
91         saveFile(className, testName, VISUALIZER_RENDERING_FILE_NAME, visualizerBitmap);
92     }
93 
dumpBitmap(Bitmap bitmap, String testName, String className)94     public static void dumpBitmap(Bitmap bitmap, String testName, String className) {
95         if (bitmap == null) {
96             Log.d(TAG, "File not saved, bitmap was null for test : " + testName);
97             return;
98         }
99         saveFile(className, testName, SINGULAR_FILE_NAME, bitmap);
100     }
101 
logIfBitmapSolidColor(String bitmapName, Bitmap bitmap)102     private static void logIfBitmapSolidColor(String bitmapName, Bitmap bitmap) {
103         int firstColor = bitmap.getPixel(0, 0);
104         for (int x = 0; x < bitmap.getWidth(); x++) {
105             for (int y = 0; y < bitmap.getHeight(); y++) {
106                 if (bitmap.getPixel(x, y) != firstColor) {
107                     return;
108                 }
109             }
110         }
111 
112         Log.w(TAG, String.format("%s entire bitmap color is %x", bitmapName, firstColor));
113     }
114 
saveFile(String className, String testName, String fileName, Bitmap bitmap)115     private static void saveFile(String className, String testName, String fileName, Bitmap bitmap) {
116         String bitmapName = testName + "_" + fileName;
117         Log.d(TAG, "Saving file : " + bitmapName + " in directory : " + className);
118         logIfBitmapSolidColor(bitmapName, bitmap);
119 
120         File file = new File(CAPTURE_SUB_DIRECTORY + className, bitmapName);
121         FileOutputStream fileStream = null;
122         try {
123             fileStream = new FileOutputStream(file);
124             bitmap.compress(Bitmap.CompressFormat.PNG, 85, fileStream);
125             fileStream.flush();
126         } catch (FileNotFoundException e) {
127             e.printStackTrace();
128         } catch (IOException e) {
129             e.printStackTrace();
130         } finally {
131             if (fileStream != null) {
132                 IoUtils.closeQuietly(fileStream);
133             }
134         }
135     }
136 }
137