1 /*
2  * Copyright (C) 2017 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 com.android.wallpaper.util;
17 
18 import android.graphics.Bitmap;
19 import android.graphics.Bitmap.Config;
20 import android.graphics.Color;
21 import android.graphics.Point;
22 
23 /**
24  * Applies fill and stretch transformations to bitmaps.
25  */
26 public class BitmapTransformer {
27 
28     // Suppress default constructor for noninstantiability.
BitmapTransformer()29     private BitmapTransformer() {
30         throw new AssertionError();
31     }
32 
33     /**
34      * Centers the provided bitmap to a new bitmap with the dimensions of fillSize and fills in any
35      * remaining empty space with black pixels.
36      */
applyFillTransformation(Bitmap bitmap, Point fillSize)37     public static Bitmap applyFillTransformation(Bitmap bitmap, Point fillSize) {
38         // Initialize a new result bitmap with all black pixels.
39         Bitmap resultBitmap = Bitmap.createBitmap(fillSize.x, fillSize.y, Config.ARGB_8888);
40         resultBitmap.eraseColor(Color.BLACK);
41 
42         // Calculate horizontal and vertical offsets between the source and result bitmaps.
43         int horizontalOffset = (bitmap.getWidth() - resultBitmap.getWidth()) / 2;
44         int verticalOffset = (bitmap.getHeight() - resultBitmap.getHeight()) / 2;
45 
46         // Allocate an int array to temporarily store a buffer of the pixel color data we are copying
47         // from the source to the final bitmap. We are only copying the portion of the source bitmap
48         // that fits within the bounds of the result bitmap, so take the lesser of both bitmap's width
49         // and height to calculate the size.
50         int pixelArraySize = Math.min(resultBitmap.getWidth(), bitmap.getWidth())
51                 * Math.min(resultBitmap.getHeight(), bitmap.getHeight());
52         int[] srcPixels = new int[pixelArraySize];
53 
54         // Copy region of source bitmap into pixel array buffer.
55         bitmap.getPixels(
56                 srcPixels,
57                 0 /* offset */,
58                 bitmap.getWidth() /* stride */,
59                 Math.max(0, horizontalOffset),
60                 Math.max(0, verticalOffset),
61                 Math.min(resultBitmap.getWidth(), bitmap.getWidth()) /* width */,
62                 Math.min(resultBitmap.getHeight(), bitmap.getHeight()) /* height */);
63 
64         // Copy the values stored in the pixel array buffer to the result bitmap.
65         resultBitmap.setPixels(
66                 srcPixels,
67                 0 /* offset */,
68                 bitmap.getWidth() /* stride */,
69                 Math.max(0, -1 * horizontalOffset),
70                 Math.max(0, -1 * verticalOffset),
71                 Math.min(resultBitmap.getWidth(), bitmap.getWidth()) /* width */,
72                 Math.min(resultBitmap.getHeight(), bitmap.getHeight()) /* height */);
73 
74         return resultBitmap;
75     }
76 }
77