What's new? | Help | Directory | Sign in
Google
                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
* Copyright (C) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.android.photostream;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;

import java.util.Random;

/**
* This class contains various utilities to manipulate Bitmaps. The methods of this class,
* although static, are not thread safe and cannot be invoked by several threads at the
* same time. Synchronization is required by the caller.
*/
final class ImageUtilities {
private static final float PHOTO_BORDER_WIDTH = 3.0f;
private static final int PHOTO_BORDER_COLOR = 0xffffffff;

private static final float ROTATION_ANGLE_MIN = 2.5f;
private static final float ROTATION_ANGLE_EXTRA = 5.5f;

private static final Random sRandom = new Random();
private static final Paint sPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
private static final Paint sStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);

static {
sStrokePaint.setStrokeWidth(PHOTO_BORDER_WIDTH);
sStrokePaint.setStyle(Paint.Style.STROKE);
sStrokePaint.setColor(PHOTO_BORDER_COLOR);
}

/**
* Rotate specified Bitmap by a random angle. The angle is either negative or positive,
* and ranges, in degrees, from 2.5 to 8. After rotation a frame is overlaid on top
* of the rotated image.
*
* This method is not thread safe.
*
* @param bitmap The Bitmap to rotate and apply a frame onto.
*
* @return A new Bitmap whose dimension are different from the original bitmap.
*/
static Bitmap rotateAndFrame(Bitmap bitmap) {
final boolean positive = sRandom.nextFloat() >= 0.5f;
final float angle = (ROTATION_ANGLE_MIN + sRandom.nextFloat() * ROTATION_ANGLE_EXTRA) *
(positive ? 1.0f : -1.0f);
final double radAngle = Math.toRadians(angle);

final int bitmapWidth = bitmap.getWidth();
final int bitmapHeight = bitmap.getHeight();

final double cosAngle = Math.abs(Math.cos(radAngle));
final double sinAngle = Math.abs(Math.sin(radAngle));

final int strokedWidth = (int) (bitmapWidth + 2 * PHOTO_BORDER_WIDTH);
final int strokedHeight = (int) (bitmapHeight + 2 * PHOTO_BORDER_WIDTH);

final int width = (int) (strokedHeight * sinAngle + strokedWidth * cosAngle);
final int height = (int) (strokedWidth * sinAngle + strokedHeight * cosAngle);

final float x = (width - bitmapWidth) / 2.0f;
final float y = (height - bitmapHeight) / 2.0f;

final Bitmap decored = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(decored);

canvas.rotate(angle, width / 2.0f, height / 2.0f);
canvas.drawBitmap(bitmap, x, y, sPaint);
canvas.drawRect(x, y, x + bitmapWidth, y + bitmapHeight, sStrokePaint);

return decored;
}

/**
* Scales the specified Bitmap to fit within the specified dimensions. After scaling,
* a frame is overlaid on top of the scaled image.
*
* This method is not thread safe.
*
* @param bitmap The Bitmap to scale to fit the specified dimensions and to apply
* a frame onto.
* @param width The maximum width of the new Bitmap.
* @param height The maximum height of the new Bitmap.
*
* @return A scaled version of the original bitmap, whose dimension are less than or
* equal to the specified width and height.
*/
static Bitmap scaleAndFrame(Bitmap bitmap, int width, int height) {
final int bitmapWidth = bitmap.getWidth();
final int bitmapHeight = bitmap.getHeight();

final float scale = Math.min((float) width / (float) bitmapWidth,
(float) height / (float) bitmapHeight);

final int scaledWidth = (int) (bitmapWidth * scale);
final int scaledHeight = (int) (bitmapHeight * scale);

final Bitmap decored = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true);
final Canvas canvas = new Canvas(decored);

final int offset = (int) (PHOTO_BORDER_WIDTH / 2);
sStrokePaint.setAntiAlias(false);
canvas.drawRect(offset, offset, scaledWidth - offset - 1,
scaledHeight - offset - 1, sStrokePaint);
sStrokePaint.setAntiAlias(true);

return decored;

}
}
Show details Hide details

Change log

r14 by romain...@google.com on Aug 29, 2008   Diff
First version of Photostream, a Flickr
photostream browser.
Go to: 
Project members, sign in to write a code review

Older revisions

All revisions of this file

File info

Size: 4964 bytes, 125 lines