Created
July 19, 2015 12:44
-
-
Save xxnjdlys/c8e06aaf3f8aaf8cce08 to your computer and use it in GitHub Desktop.
mix bitmap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.sadieyu.mixbitmapsdemo; | |
import android.app.Activity; | |
import android.graphics.Bitmap; | |
import android.graphics.Canvas; | |
import android.graphics.Matrix; | |
import android.graphics.PointF; | |
import android.graphics.Rect; | |
import android.graphics.drawable.Drawable; | |
import android.os.Bundle; | |
import android.view.View; | |
import android.widget.Button; | |
import android.widget.ImageView; | |
public class MainActivity extends Activity { | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
// ContextThemeWrapper.getTheme(); | |
Drawable d1 = getResources().getDrawable(R.drawable.ic1/*,getTheme()*/); | |
Drawable d2 = getResources().getDrawable(R.drawable.ic2/*,getTheme()*/); | |
Drawable d3 = getResources().getDrawable(R.drawable.ic3/*,getTheme()*/); | |
Drawable d4 = getResources().getDrawable(R.drawable.ic4/*,getTheme()*/); | |
Bitmap b1 = miniThumb(drawableToBitmap(d1), 60, 60); | |
Bitmap b2 = miniThumb(drawableToBitmap(d2), 60, 60); | |
Bitmap b3 = miniThumb(drawableToBitmap(d3), 60, 60); | |
Bitmap b4 = miniThumb(drawableToBitmap(d4), 60, 60); | |
Bitmap[] list = {b1, b2, b3, b4}; | |
Bitmap bitmap = combineBitmaps(8, list); | |
ImageView img = (ImageView) findViewById(R.id.result); | |
img.setImageBitmap(bitmap); | |
Button btn = (Button) findViewById(R.id.mix); | |
btn.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
} | |
}); | |
} | |
public static Bitmap combineBitmaps(int columns, Bitmap... bitmaps) { | |
if (columns <= 0 || bitmaps == null || bitmaps.length == 0) { | |
throw new IllegalArgumentException("Wrong parameters: columns must > 0 and bitmaps.length must > 0."); | |
} | |
int maxWidthPerImage = 0; | |
int maxHeightPerImage = 0; | |
for (Bitmap b : bitmaps) { | |
maxWidthPerImage = maxWidthPerImage > b.getWidth() ? maxWidthPerImage : b.getWidth(); | |
maxHeightPerImage = maxHeightPerImage > b.getHeight() ? maxHeightPerImage : b.getHeight(); | |
} | |
int rows = 0; | |
if (columns >= bitmaps.length) { | |
rows = 1; | |
columns = bitmaps.length; | |
} else { | |
rows = bitmaps.length % columns == 0 ? bitmaps.length / columns : bitmaps.length / columns + 1; | |
} | |
Bitmap newBitmap = Bitmap.createBitmap(columns * maxWidthPerImage, rows * maxHeightPerImage, Bitmap.Config.ALPHA_8); | |
for (int x = 0; x < rows; x++) { | |
for (int y = 0; y < columns; y++) { | |
int index = x * columns + y; | |
if (index >= bitmaps.length) | |
break; | |
newBitmap = mixtureBitmap(newBitmap, bitmaps[index], new PointF(y * maxWidthPerImage, x * maxHeightPerImage)); | |
} | |
} | |
return newBitmap; | |
} | |
//从任一Drawable得到Bitmap | |
public static Bitmap drawableToBitmap(Drawable drawable) { | |
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.RGB_565); | |
Canvas canvas = new Canvas(bitmap); | |
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); | |
drawable.draw(canvas); | |
return bitmap; | |
} | |
/** | |
* Mix two Bitmap as one. | |
* where the second bitmap is painted. | |
* | |
* @return | |
*/ | |
public static Bitmap mixtureBitmap(Bitmap first, Bitmap second, PointF fromPoint) { | |
if (first == null || second == null || fromPoint == null) { | |
return null; | |
} | |
Bitmap newBitmap = Bitmap.createBitmap(first.getWidth(), first.getHeight(), Bitmap.Config.ARGB_4444); | |
Canvas cv = new Canvas(newBitmap); | |
// Paint paint = new Paint(); | |
// paint.setAlpha(255); | |
cv.drawBitmap(first, 0, 0, null); | |
cv.drawBitmap(second, fromPoint.x, fromPoint.y, null); | |
cv.save(Canvas.ALL_SAVE_FLAG); | |
cv.restore(); | |
return newBitmap; | |
} | |
/** | |
* Creates a centered bitmap of the desired size. Recycles the input. | |
* | |
* @param source | |
*/ | |
public static Bitmap miniThumb(Bitmap source, int width, int height) { | |
return extractMiniThumb(source, width, height, true); | |
} | |
public static Bitmap extractMiniThumb(Bitmap source, int width, int height, boolean recycle) { | |
if (source == null) { | |
return null; | |
} | |
float scale; | |
if (source.getWidth() < source.getHeight()) { | |
scale = width / (float) source.getWidth(); | |
} else { | |
scale = height / (float) source.getHeight(); | |
} | |
Matrix matrix = new Matrix(); | |
matrix.setScale(scale, scale); | |
Bitmap miniThumbnail = transform(matrix, source, width, height, false); | |
if (recycle && miniThumbnail != source) { | |
source.recycle(); | |
} | |
return miniThumbnail; | |
} | |
public static Bitmap transform(Matrix scaler, Bitmap source, int targetWidth, int targetHeight, boolean scaleUp) { | |
int deltaX = source.getWidth() - targetWidth; | |
int deltaY = source.getHeight() - targetHeight; | |
if (!scaleUp && (deltaX < 0 || deltaY < 0)) { | |
/* | |
* In this case the bitmap is smaller, at least in one dimension, | |
* than the target. Transform it by placing as much of the image as | |
* possible into the target and leaving the top/bottom or left/right | |
* (or both) black. | |
*/ | |
Bitmap b2 = Bitmap.createBitmap(targetWidth, targetHeight, Bitmap.Config.ARGB_8888); | |
Canvas c = new Canvas(b2); | |
int deltaXHalf = Math.max(0, deltaX / 2); | |
int deltaYHalf = Math.max(0, deltaY / 2); | |
Rect src = new Rect(deltaXHalf, deltaYHalf, deltaXHalf + Math.min(targetWidth, source.getWidth()), deltaYHalf | |
+ Math.min(targetHeight, source.getHeight())); | |
int dstX = (targetWidth - src.width()) / 2; | |
int dstY = (targetHeight - src.height()) / 2; | |
Rect dst = new Rect(dstX, dstY, targetWidth - dstX, targetHeight - dstY); | |
c.drawBitmap(source, src, dst, null); | |
return b2; | |
} | |
float bitmapWidthF = source.getWidth(); | |
float bitmapHeightF = source.getHeight(); | |
float bitmapAspect = bitmapWidthF / bitmapHeightF; | |
float viewAspect = (float) targetWidth / targetHeight; | |
if (bitmapAspect > viewAspect) { | |
float scale = targetHeight / bitmapHeightF; | |
if (scale < .9F || scale > 1F) { | |
scaler.setScale(scale, scale); | |
} else { | |
scaler = null; | |
} | |
} else { | |
float scale = targetWidth / bitmapWidthF; | |
if (scale < .9F || scale > 1F) { | |
scaler.setScale(scale, scale); | |
} else { | |
scaler = null; | |
} | |
} | |
Bitmap b1; | |
if (scaler != null) { | |
// this is used for minithumb and crop, so we want to filter here. | |
b1 = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), scaler, true); | |
} else { | |
b1 = source; | |
} | |
int dx1 = Math.max(0, b1.getWidth() - targetWidth); | |
int dy1 = Math.max(0, b1.getHeight() - targetHeight); | |
Bitmap b2 = Bitmap.createBitmap(b1, dx1 / 2, dy1 / 2, targetWidth, targetHeight); | |
if (b1 != source) { | |
b1.recycle(); | |
} | |
return b2; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment