Android Tutorial - 2D Graphics : Bitmap
Using BitmapFactory to decode Resource
package app.test; import android.app.Activity; import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.widget.ImageView; public class Test extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ImageView imgView = (ImageView)findViewById(R.id.image3); imgView.setImageBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.icon) ); } } //main.xml <?xml version="1.0" encoding="utf-8"?> <!-- This file is at /res/layout/list.xml --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="fill_parent"> <ImageView android:id="@+id/image1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon" /> <ImageView android:id="@+id/image2" android:layout_width="125dip" android:layout_height="25dip" android:src="#555555" /> </LinearLayout> <LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="fill_parent"> <ImageView android:id="@+id/image3" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageView android:id="@+id/image4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon" android:scaleType="centerInside" android:maxWidth="35dip" android:maxHeight="50dip" /> </LinearLayout> </LinearLayout>
Capture and save to Bitmap
package app.test; import java.io.File; import android.app.Activity; import android.content.ContentValues; import android.content.Intent; import android.content.pm.ActivityInfo; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import android.provider.MediaStore.Images.Media; import android.util.Log; import android.view.View; public class Test extends Activity { Uri myPicture = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } public void captureImage(View view) { Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(i, 0); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(requestCode==0 && resultCode==Activity.RESULT_OK) { Bitmap myBitmap = (Bitmap) data.getExtras().get("data"); } } }
Bitmap size
package app.test; import java.io.File; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.view.Display; import android.widget.ImageView; public class Test extends Activity { final static int CAMERA_RESULT = 0; ImageView imv; String imageFilePath; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); imageFilePath = Environment.getExternalStorageDirectory().getAbsolutePath()+ "/a.jpg"; File imageFile = new File(imageFilePath); Uri imageFileUri = Uri.fromFile(imageFile); Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri); startActivityForResult(i, CAMERA_RESULT); } protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); if (resultCode == RESULT_OK) { imv = (ImageView) findViewById(R.id.ReturnedImageView); Display currentDisplay = getWindowManager().getDefaultDisplay(); BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions); bmpFactoryOptions.inSampleSize = 2; bmpFactoryOptions.inJustDecodeBounds = false; bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions); imv.setImageBitmap(bmp); } } } //layout/main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ImageView android:id="@+id/ReturnedImageView" android:layout_width="wrap_content" android:layout_height="wrap_content"></ImageView> </LinearLayout>
Draw Bitmap on Canvas
package app.test; import java.io.FileNotFoundException; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class Test extends Activity implements OnClickListener { ImageView chosenImageView; Button choosePicture; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); chosenImageView = (ImageView) this.findViewById(R.id.ChosenImageView); choosePicture = (Button) this.findViewById(R.id.ChoosePictureButton); choosePicture.setOnClickListener(this); } public void onClick(View v) { Intent choosePictureIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(choosePictureIntent, 0); } protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); if (resultCode == RESULT_OK) { Uri imageFileUri = intent.getData(); try { BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream( imageFileUri), null, bmpFactoryOptions); bmpFactoryOptions.inSampleSize = 2; bmpFactoryOptions.inJustDecodeBounds = false; bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream( imageFileUri), null, bmpFactoryOptions); Bitmap alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp .getHeight(), bmp.getConfig()); Canvas canvas = new Canvas(alteredBitmap); Paint paint = new Paint(); canvas.drawBitmap(bmp, 0, 0, paint); ImageView alteredImageView = (ImageView) this .findViewById(R.id.AlteredImageView); alteredImageView.setImageBitmap(alteredBitmap); chosenImageView.setImageBitmap(bmp); } catch (FileNotFoundException e) { Log.v("ERROR", e.toString()); } } } } //main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Choose Picture" android:id="@+id/ChoosePictureButton"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/ChosenImageView"></ImageView> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/AlteredImageView"></ImageView> </LinearLayout>
Bitmap.createBitmap
package app.test; import java.io.FileNotFoundException; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuffXfermode; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.Display; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class Test extends Activity implements OnClickListener { Button choosePicture1, choosePicture2; ImageView compositeImageView; Bitmap bmp1, bmp2; Canvas canvas; Paint paint; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); compositeImageView = (ImageView) this .findViewById(R.id.CompositeImageView); choosePicture1 = (Button) this.findViewById(R.id.ChoosePictureButton1); choosePicture2 = (Button) this.findViewById(R.id.ChoosePictureButton2); choosePicture1.setOnClickListener(this); choosePicture2.setOnClickListener(this); } public void onClick(View v) { Intent choosePictureIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(choosePictureIntent, 1); } protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); if (resultCode == RESULT_OK) { Uri imageFileUri = intent.getData(); bmp1 = loadBitmap(imageFileUri); Bitmap drawingBitmap = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig()); canvas = new Canvas(drawingBitmap); paint = new Paint(); canvas.drawBitmap(bmp1, 0, 0, paint); paint.setXfermode(new PorterDuffXfermode( android.graphics.PorterDuff.Mode.MULTIPLY)); canvas.drawBitmap(bmp2, 0, 0, paint); compositeImageView.setImageBitmap(drawingBitmap); } } private Bitmap loadBitmap(Uri imageFileUri) { Display currentDisplay = getWindowManager().getDefaultDisplay(); float dw = currentDisplay.getWidth(); float dh = currentDisplay.getHeight(); Bitmap returnBmp = Bitmap.createBitmap((int) dw, (int) dh, Bitmap.Config.ARGB_4444); try { BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inJustDecodeBounds = true; returnBmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpFactoryOptions); bmpFactoryOptions.inSampleSize = 2; bmpFactoryOptions.inJustDecodeBounds = false; returnBmp = BitmapFactory.decodeStream(getContentResolver() .openInputStream(imageFileUri), null, bmpFactoryOptions); } catch (Exception e) { Log.v("ERROR", e.toString()); } return returnBmp; } }
Draw Bitmap on Canvas with Matrix
package app.test; import java.io.FileNotFoundException; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.Display; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class Test extends Activity implements OnClickListener { ImageView chosenImageView; Button choosePicture; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); chosenImageView = (ImageView) this.findViewById(R.id.ChosenImageView); choosePicture = (Button) this.findViewById(R.id.ChoosePictureButton); choosePicture.setOnClickListener(this); } public void onClick(View v) { Intent choosePictureIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(choosePictureIntent, 0); } protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); if (resultCode == RESULT_OK) { Uri imageFileUri = intent.getData(); Display currentDisplay = getWindowManager().getDefaultDisplay(); int dw = currentDisplay.getWidth(); int dh = currentDisplay.getHeight() / 2 - 100; try { BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream( imageFileUri), null, bmpFactoryOptions); bmpFactoryOptions.inSampleSize = 2; bmpFactoryOptions.inJustDecodeBounds = false; bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream( imageFileUri), null, bmpFactoryOptions); Bitmap alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp .getHeight(), bmp.getConfig()); Canvas canvas = new Canvas(alteredBitmap); Paint paint = new Paint(); canvas.drawBitmap(bmp, 0, 0, paint); Matrix matrix = new Matrix(); matrix.setValues(new float[] { 1, .5f, 0, 0, 1, 0, 0, 0, 1 }); canvas.drawBitmap(bmp, matrix, paint); ImageView alteredImageView = (ImageView) this.findViewById(R.id.AlteredImageView); alteredImageView.setImageBitmap(alteredBitmap); chosenImageView.setImageBitmap(bmp); } catch (Exception e) { Log.v("ERROR", e.toString()); } } } } //main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Choose Picture" android:id="@+id/ChoosePictureButton"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/ChosenImageView"></ImageView> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/AlteredImageView"></ImageView> </LinearLayout>
Create a Bitmap for drawing
package app.test; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Typeface; import android.os.Bundle; import android.widget.ImageView; public class Test extends Activity { ImageView drawingImageView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); drawingImageView = (ImageView) this.findViewById(R.id.DrawingImageView); Bitmap bitmap = Bitmap.createBitmap((int) getWindowManager() .getDefaultDisplay().getWidth(), (int) getWindowManager() .getDefaultDisplay().getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawingImageView.setImageBitmap(bitmap); Paint paint = new Paint(); paint.setColor(Color.GREEN); paint.setTextSize(20); paint.setTypeface(Typeface.DEFAULT); Path p = new Path(); p.moveTo(20, 20); p.lineTo(100, 150); p.lineTo(200, 220); canvas.drawTextOnPath("this is a test", p, 0, 0, paint); } }
Load Bitmap and Draw
package app.test; import java.io.IOException; import java.io.InputStream; import android.app.Activity; import android.content.Context; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Rect; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.Window; import android.view.WindowManager; public class Test extends Activity { class RenderView extends View { Bitmap bitmap1; Bitmap bitmap2; Rect dst = new Rect(); public RenderView(Context context) { super(context); try { AssetManager assetManager = context.getAssets(); InputStream inputStream = assetManager.open("a.png"); bitmap1 = BitmapFactory.decodeStream(inputStream); inputStream.close(); Log.d("Text",""+bitmap1.getConfig()); inputStream = assetManager.open("b.png"); BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.ARGB_4444; bitmap2 = BitmapFactory.decodeStream(inputStream, null, options); inputStream.close(); Log.d("BitmapText","" + bitmap2.getConfig()); } catch (IOException e) { } } protected void onDraw(Canvas canvas) { dst.set(50, 50, 350, 350); canvas.drawBitmap(bitmap1, null, dst, null); canvas.drawBitmap(bitmap2, 100, 100, null); invalidate(); } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(new RenderView(this)); } }
package com.example.android.rs.hellocompute; import android.app.Activity; import android.os.Bundle; import android.graphics.BitmapFactory; import android.graphics.Bitmap; import android.renderscript.RenderScript; import android.renderscript.Allocation; import android.widget.ImageView; public class HelloCompute extends Activity { private Bitmap mBitmapIn; private Bitmap mBitmapOut; private RenderScript mRS; private Allocation mInAllocation; private Allocation mOutAllocation; private ScriptC_mono mScript; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mBitmapIn = loadBitmap(R.drawable.data); mBitmapOut = Bitmap.createBitmap(mBitmapIn.getWidth(), mBitmapIn.getHeight(), mBitmapIn.getConfig()); ImageView in = (ImageView) findViewById(R.id.displayin); in.setImageBitmap(mBitmapIn); ImageView out = (ImageView) findViewById(R.id.displayout); out.setImageBitmap(mBitmapOut); createScript(); } private void createScript() { mRS = RenderScript.create(this); mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); mOutAllocation = Allocation.createTyped(mRS, mInAllocation.getType()); mScript = new ScriptC_mono(mRS, getResources(), R.raw.mono); mScript.set_gIn(mInAllocation); mScript.set_gOut(mOutAllocation); mScript.set_gScript(mScript); mScript.invoke_filter(); mOutAllocation.copyTo(mBitmapOut); } private Bitmap loadBitmap(int resource) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.ARGB_8888; return BitmapFactory.decodeResource(getResources(), resource, options); } } //src\com\example\android\rs\hellocompute\mono.rs /* * Copyright (C) 2011 The Android Open Source Project * * 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. */ #pragma version(1) #pragma rs java_package_name(com.example.android.rs.hellocompute) rs_allocation gIn; rs_allocation gOut; rs_script gScript; const static float3 gMonoMult = {0.299f, 0.587f, 0.114f}; void root(const uchar4 *v_in, uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y) { float4 f4 = rsUnpackColor8888(*v_in); float3 mono = dot(f4.rgb, gMonoMult); *v_out = rsPackColorTo8888(mono); } void filter() { rsForEach(gScript, gIn, gOut, 0); } // //res\layout\main.xml <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2011 The Android Open Source Project 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. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/displayin" android:layout_width="320dip" android:layout_height="266dip" /> <ImageView android:id="@+id/displayout" android:layout_width="320dip" android:layout_height="266dip" /> </LinearLayout>
Alpha Bitmap
package app.test; import java.io.InputStream; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.Picture; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.Shader; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; public class Test extends GraphicsActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new SampleView(this)); } private static class SampleView extends View { private Bitmap mBitmap; private Bitmap mBitmap2; private Bitmap mBitmap3; private Shader mShader; private static void drawIntoBitmap(Bitmap bm) { float x = bm.getWidth(); float y = bm.getHeight(); Canvas c = new Canvas(bm); Paint p = new Paint(); p.setAntiAlias(true); p.setAlpha(0x80); c.drawCircle(x/2, y/2, x/2, p); p.setAlpha(0x30); p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); p.setTextSize(60); p.setTextAlign(Paint.Align.CENTER); Paint.FontMetrics fm = p.getFontMetrics(); c.drawText("Alpha", x/2, (y-fm.ascent)/2, p); } public SampleView(Context context) { super(context); setFocusable(true); InputStream is = context.getResources().openRawResource(R.drawable.icon); mBitmap = BitmapFactory.decodeStream(is); mBitmap2 = mBitmap.extractAlpha(); mBitmap3 = Bitmap.createBitmap(200, 200, Bitmap.Config.ALPHA_8); drawIntoBitmap(mBitmap3); mShader = new LinearGradient(0, 0, 100, 70, new int[] { Color.RED, Color.GREEN, Color.BLUE }, null, Shader.TileMode.MIRROR); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(Color.WHITE); Paint p = new Paint(); float y = 10; p.setColor(Color.RED); canvas.drawBitmap(mBitmap, 10, y, p); y += mBitmap.getHeight() + 10; canvas.drawBitmap(mBitmap2, 10, y, p); y += mBitmap2.getHeight() + 10; p.setShader(mShader); canvas.drawBitmap(mBitmap3, 10, y, p); } } } class GraphicsActivity extends Activity { // set to true to test Picture private static final boolean TEST_PICTURE = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void setContentView(View view) { if (TEST_PICTURE) { ViewGroup vg = new PictureLayout(this); vg.addView(view); view = vg; } super.setContentView(view); } } class PictureLayout extends ViewGroup { private final Picture mPicture = new Picture(); public PictureLayout(Context context) { super(context); } public PictureLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void addView(View child) { if (getChildCount() > 1) { throw new IllegalStateException("PictureLayout can host only one direct child"); } super.addView(child); } @Override public void addView(View child, int index) { if (getChildCount() > 1) { throw new IllegalStateException("PictureLayout can host only one direct child"); } super.addView(child, index); } @Override public void addView(View child, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException("PictureLayout can host only one direct child"); } super.addView(child, params); } @Override public void addView(View child, int index, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException("PictureLayout can host only one direct child"); } super.addView(child, index, params); } @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int count = getChildCount(); int maxHeight = 0; int maxWidth = 0; for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { measureChild(child, widthMeasureSpec, heightMeasureSpec); } } maxWidth += getPaddingLeft() + getPaddingRight(); maxHeight += getPaddingTop() + getPaddingBottom(); Drawable drawable = getBackground(); if (drawable != null) { maxHeight = Math.max(maxHeight, drawable.getMinimumHeight()); maxWidth = Math.max(maxWidth, drawable.getMinimumWidth()); } setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec), resolveSize(maxHeight, heightMeasureSpec)); } private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx, float sy) { canvas.save(); canvas.translate(x, y); canvas.clipRect(0, 0, w, h); canvas.scale(0.5f, 0.5f); canvas.scale(sx, sy, w, h); canvas.drawPicture(mPicture); canvas.restore(); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight())); mPicture.endRecording(); int x = getWidth()/2; int y = getHeight()/2; if (false) { canvas.drawPicture(mPicture); } else { drawPict(canvas, 0, 0, x, y, 1, 1); drawPict(canvas, x, 0, x, y, -1, 1); drawPict(canvas, 0, y, x, y, 1, -1); drawPict(canvas, x, y, x, y, -1, -1); } } @Override public ViewParent invalidateChildInParent(int[] location, Rect dirty) { location[0] = getLeft(); location[1] = getTop(); dirty.set(0, 0, getWidth(), getHeight()); return getParent(); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = super.getChildCount(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final int childLeft = getPaddingLeft(); final int childTop = getPaddingTop(); child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); } } } }
Load Bitmap from InputStream
import java.io.InputStream; import java.net.URL; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; class BitmapImageUtil { public static Bitmap loadFrom(String url, Context context, int defaultDrawable) { try { InputStream is = (InputStream) new URL(url).getContent(); try { return BitmapFactory.decodeStream(is); } finally { is.close(); } } catch (Exception e) { return BitmapFactory.decodeResource(context.getResources(), defaultDrawable); } } }
package app.test; import java.io.ByteArrayOutputStream; import java.io.InputStream; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Movie; import android.graphics.Paint; import android.graphics.Picture; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; public class Test extends GraphicsActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new SampleView(this)); } private static class SampleView extends View { private Bitmap mBitmap; private Bitmap mBitmap2; private Bitmap mBitmap3; private Bitmap mBitmap4; private Drawable mDrawable; private Movie mMovie; private long mMovieStart; // Set to false to use decodeByteArray private static final boolean DECODE_STREAM = true; private static byte[] streamToBytes(InputStream is) { ByteArrayOutputStream os = new ByteArrayOutputStream(1024); byte[] buffer = new byte[1024]; int len; try { while ((len = is.read(buffer)) >= 0) { os.write(buffer, 0, len); } } catch (java.io.IOException e) { } return os.toByteArray(); } public SampleView(Context context) { super(context); setFocusable(true); java.io.InputStream is; is = context.getResources().openRawResource(R.drawable.icon); BitmapFactory.Options opts = new BitmapFactory.Options(); Bitmap bm; opts.inJustDecodeBounds = true; bm = BitmapFactory.decodeStream(is, null, opts); // now opts.outWidth and opts.outHeight are the dimension of the // bitmap, even though bm is null opts.inJustDecodeBounds = false; // this will request the bm opts.inSampleSize = 4; // scaled down by 4 bm = BitmapFactory.decodeStream(is, null, opts); mBitmap = bm; // decode an image with transparency is = context.getResources().openRawResource(R.drawable.icon); mBitmap2 = BitmapFactory.decodeStream(is); // create a deep copy of it using getPixels() into different configs int w = mBitmap2.getWidth(); int h = mBitmap2.getHeight(); int[] pixels = new int[w * h]; mBitmap2.getPixels(pixels, 0, w, 0, 0, w, h); mBitmap3 = Bitmap.createBitmap(pixels, 0, w, w, h, Bitmap.Config.ARGB_8888); mBitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h, Bitmap.Config.ARGB_4444); mDrawable = context.getResources().getDrawable(R.drawable.icon); mDrawable.setBounds(150, 20, 300, 100); is = context.getResources().openRawResource(R.drawable.animated_gif); if (DECODE_STREAM) { mMovie = Movie.decodeStream(is); } else { byte[] array = streamToBytes(is); mMovie = Movie.decodeByteArray(array, 0, array.length); } } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(0xFFCCCCCC); Paint p = new Paint(); p.setAntiAlias(true); canvas.drawBitmap(mBitmap, 10, 10, null); canvas.drawBitmap(mBitmap2, 10, 170, null); canvas.drawBitmap(mBitmap3, 110, 170, null); canvas.drawBitmap(mBitmap4, 210, 170, null); mDrawable.draw(canvas); long now = android.os.SystemClock.uptimeMillis(); if (mMovieStart == 0) { // first time mMovieStart = now; } if (mMovie != null) { int dur = mMovie.duration(); if (dur == 0) { dur = 1000; } int relTime = (int) ((now - mMovieStart) % dur); mMovie.setTime(relTime); mMovie.draw(canvas, getWidth() - mMovie.width(), getHeight() - mMovie.height()); invalidate(); } } } } class GraphicsActivity extends Activity { // set to true to test Picture private static final boolean TEST_PICTURE = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void setContentView(View view) { if (TEST_PICTURE) { ViewGroup vg = new PictureLayout(this); vg.addView(view); view = vg; } super.setContentView(view); } } class PictureLayout extends ViewGroup { private final Picture mPicture = new Picture(); public PictureLayout(Context context) { super(context); } public PictureLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void addView(View child) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child); } @Override public void addView(View child, int index) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index); } @Override public void addView(View child, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, params); } @Override public void addView(View child, int index, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index, params); } @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int count = getChildCount(); int maxHeight = 0; int maxWidth = 0; for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { measureChild(child, widthMeasureSpec, heightMeasureSpec); } } maxWidth += getPaddingLeft() + getPaddingRight(); maxHeight += getPaddingTop() + getPaddingBottom(); Drawable drawable = getBackground(); if (drawable != null) { maxHeight = Math.max(maxHeight, drawable.getMinimumHeight()); maxWidth = Math.max(maxWidth, drawable.getMinimumWidth()); } setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec), resolveSize(maxHeight, heightMeasureSpec)); } private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx, float sy) { canvas.save(); canvas.translate(x, y); canvas.clipRect(0, 0, w, h); canvas.scale(0.5f, 0.5f); canvas.scale(sx, sy, w, h); canvas.drawPicture(mPicture); canvas.restore(); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight())); mPicture.endRecording(); int x = getWidth() / 2; int y = getHeight() / 2; if (false) { canvas.drawPicture(mPicture); } else { drawPict(canvas, 0, 0, x, y, 1, 1); drawPict(canvas, x, 0, x, y, -1, 1); drawPict(canvas, 0, y, x, y, 1, -1); drawPict(canvas, x, y, x, y, -1, -1); } } @Override public ViewParent invalidateChildInParent(int[] location, Rect dirty) { location[0] = getLeft(); location[1] = getTop(); dirty.set(0, 0, getWidth(), getHeight()); return getParent(); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = super.getChildCount(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final int childLeft = getPaddingLeft(); final int childTop = getPaddingTop(); child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); } } } }
package app.test; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Picture; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.AttributeSet; import android.util.FloatMath; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; public class Test extends GraphicsActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new SampleView(this)); } private static class SampleView extends View { private static final int WIDTH = 20; private static final int HEIGHT = 20; private static final int COUNT = (WIDTH + 1) * (HEIGHT + 1); private final Bitmap mBitmap; private final float[] mVerts = new float[COUNT*2]; private final float[] mOrig = new float[COUNT*2]; private final Matrix mMatrix = new Matrix(); private final Matrix mInverse = new Matrix(); private static void setXY(float[] array, int index, float x, float y) { array[index*2 + 0] = x; array[index*2 + 1] = y; } public SampleView(Context context) { super(context); setFocusable(true); mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon); float w = mBitmap.getWidth(); float h = mBitmap.getHeight(); // construct our mesh int index = 0; for (int y = 0; y <= HEIGHT; y++) { float fy = h * y / HEIGHT; for (int x = 0; x <= WIDTH; x++) { float fx = w * x / WIDTH; setXY(mVerts, index, fx, fy); setXY(mOrig, index, fx, fy); index += 1; } } mMatrix.setTranslate(10, 10); mMatrix.invert(mInverse); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(0xFFCCCCCC); canvas.concat(mMatrix); canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, mVerts, 0, null, 0, null); } private void warp(float cx, float cy) { final float K = 10000; float[] src = mOrig; float[] dst = mVerts; for (int i = 0; i < COUNT*2; i += 2) { float x = src[i+0]; float y = src[i+1]; float dx = cx - x; float dy = cy - y; float dd = dx*dx + dy*dy; float d = FloatMath.sqrt(dd); float pull = K / (dd + 0.000001f); pull /= (d + 0.000001f); // android.util.Log.d("skia", "index " + i + " dist=" + d + " pull=" + pull); if (pull >= 1) { dst[i+0] = cx; dst[i+1] = cy; } else { dst[i+0] = x + dx * pull; dst[i+1] = y + dy * pull; } } } private int mLastWarpX = -9999; // don't match a touch coordinate private int mLastWarpY; @Override public boolean onTouchEvent(MotionEvent event) { float[] pt = { event.getX(), event.getY() }; mInverse.mapPoints(pt); int x = (int)pt[0]; int y = (int)pt[1]; if (mLastWarpX != x || mLastWarpY != y) { mLastWarpX = x; mLastWarpY = y; warp(pt[0], pt[1]); invalidate(); } return true; } } } class GraphicsActivity extends Activity { // set to true to test Picture private static final boolean TEST_PICTURE = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void setContentView(View view) { if (TEST_PICTURE) { ViewGroup vg = new PictureLayout(this); vg.addView(view); view = vg; } super.setContentView(view); } } class PictureLayout extends ViewGroup { private final Picture mPicture = new Picture(); public PictureLayout(Context context) { super(context); } public PictureLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void addView(View child) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child); } @Override public void addView(View child, int index) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index); } @Override public void addView(View child, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, params); } @Override public void addView(View child, int index, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index, params); } @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int count = getChildCount(); int maxHeight = 0; int maxWidth = 0; for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { measureChild(child, widthMeasureSpec, heightMeasureSpec); } } maxWidth += getPaddingLeft() + getPaddingRight(); maxHeight += getPaddingTop() + getPaddingBottom(); Drawable drawable = getBackground(); if (drawable != null) { maxHeight = Math.max(maxHeight, drawable.getMinimumHeight()); maxWidth = Math.max(maxWidth, drawable.getMinimumWidth()); } setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec), resolveSize(maxHeight, heightMeasureSpec)); } private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx, float sy) { canvas.save(); canvas.translate(x, y); canvas.clipRect(0, 0, w, h); canvas.scale(0.5f, 0.5f); canvas.scale(sx, sy, w, h); canvas.drawPicture(mPicture); canvas.restore(); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight())); mPicture.endRecording(); int x = getWidth() / 2; int y = getHeight() / 2; if (false) { canvas.drawPicture(mPicture); } else { drawPict(canvas, 0, 0, x, y, 1, 1); drawPict(canvas, x, 0, x, y, -1, 1); drawPict(canvas, 0, y, x, y, 1, -1); drawPict(canvas, x, y, x, y, -1, -1); } } @Override public ViewParent invalidateChildInParent(int[] location, Rect dirty) { location[0] = getLeft(); location[1] = getTop(); dirty.set(0, 0, getWidth(), getHeight()); return getParent(); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = super.getChildCount(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final int childLeft = getPaddingLeft(); final int childTop = getPaddingTop(); child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); } } } }
package app.test; import java.nio.IntBuffer; import java.nio.ShortBuffer; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Picture; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; public class Test extends GraphicsActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new SampleView(this)); } private static class SampleView extends View { private Bitmap mBitmap1; private Bitmap mBitmap2; private Bitmap mBitmap3; // access the red component from a premultiplied color private static int getR32(int c) { return (c >> 0) & 0xFF; } // access the red component from a premultiplied color private static int getG32(int c) { return (c >> 8) & 0xFF; } // access the red component from a premultiplied color private static int getB32(int c) { return (c >> 16) & 0xFF; } // access the red component from a premultiplied color private static int getA32(int c) { return (c >> 24) & 0xFF; } /** * This takes components that are already in premultiplied form, and * packs them into an int in the correct device order. */ private static int pack8888(int r, int g, int b, int a) { return (r << 0) | (g << 8) | (b << 16) | (a << 24); } private static short pack565(int r, int g, int b) { return (short) ((r << 11) | (g << 5) | (b << 0)); } private static short pack4444(int r, int g, int b, int a) { return (short) ((a << 0) | (b << 4) | (g << 8) | (r << 12)); } private static int mul255(int c, int a) { int prod = c * a + 128; return (prod + (prod >> 8)) >> 8; } /** * Turn a color int into a premultiplied device color */ private static int premultiplyColor(int c) { int r = Color.red(c); int g = Color.green(c); int b = Color.blue(c); int a = Color.alpha(c); // now apply the alpha to r, g, b r = mul255(r, a); g = mul255(g, a); b = mul255(b, a); // now pack it in the correct order return pack8888(r, g, b, a); } private static void makeRamp(int from, int to, int n, int[] ramp8888, short[] ramp565, short[] ramp4444) { int r = getR32(from) << 23; int g = getG32(from) << 23; int b = getB32(from) << 23; int a = getA32(from) << 23; // now compute our step amounts per componenet (biased by 23 bits) int dr = ((getR32(to) << 23) - r) / (n - 1); int dg = ((getG32(to) << 23) - g) / (n - 1); int db = ((getB32(to) << 23) - b) / (n - 1); int da = ((getA32(to) << 23) - a) / (n - 1); for (int i = 0; i < n; i++) { ramp8888[i] = pack8888(r >> 23, g >> 23, b >> 23, a >> 23); ramp565[i] = pack565(r >> (23 + 3), g >> (23 + 2), b >> (23 + 3)); ramp4444[i] = pack4444(r >> (23 + 4), g >> (23 + 4), b >> (23 + 4), a >> (23 + 4)); r += dr; g += dg; b += db; a += da; } } private static IntBuffer makeBuffer(int[] src, int n) { IntBuffer dst = IntBuffer.allocate(n * n); for (int i = 0; i < n; i++) { dst.put(src); } dst.rewind(); return dst; } private static ShortBuffer makeBuffer(short[] src, int n) { ShortBuffer dst = ShortBuffer.allocate(n * n); for (int i = 0; i < n; i++) { dst.put(src); } dst.rewind(); return dst; } public SampleView(Context context) { super(context); setFocusable(true); final int N = 100; int[] data8888 = new int[N]; short[] data565 = new short[N]; short[] data4444 = new short[N]; makeRamp(premultiplyColor(Color.RED), premultiplyColor(Color.GREEN), N, data8888, data565, data4444); mBitmap1 = Bitmap.createBitmap(N, N, Bitmap.Config.ARGB_8888); mBitmap2 = Bitmap.createBitmap(N, N, Bitmap.Config.RGB_565); mBitmap3 = Bitmap.createBitmap(N, N, Bitmap.Config.ARGB_4444); mBitmap1.copyPixelsFromBuffer(makeBuffer(data8888, N)); mBitmap2.copyPixelsFromBuffer(makeBuffer(data565, N)); mBitmap3.copyPixelsFromBuffer(makeBuffer(data4444, N)); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(0xFFCCCCCC); int y = 10; canvas.drawBitmap(mBitmap1, 10, y, null); y += mBitmap1.getHeight() + 10; canvas.drawBitmap(mBitmap2, 10, y, null); y += mBitmap2.getHeight() + 10; canvas.drawBitmap(mBitmap3, 10, y, null); } } } class GraphicsActivity extends Activity { // set to true to test Picture private static final boolean TEST_PICTURE = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void setContentView(View view) { if (TEST_PICTURE) { ViewGroup vg = new PictureLayout(this); vg.addView(view); view = vg; } super.setContentView(view); } } class PictureLayout extends ViewGroup { private final Picture mPicture = new Picture(); public PictureLayout(Context context) { super(context); } public PictureLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void addView(View child) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child); } @Override public void addView(View child, int index) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index); } @Override public void addView(View child, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, params); } @Override public void addView(View child, int index, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index, params); } @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int count = getChildCount(); int maxHeight = 0; int maxWidth = 0; for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { measureChild(child, widthMeasureSpec, heightMeasureSpec); } } maxWidth += getPaddingLeft() + getPaddingRight(); maxHeight += getPaddingTop() + getPaddingBottom(); Drawable drawable = getBackground(); if (drawable != null) { maxHeight = Math.max(maxHeight, drawable.getMinimumHeight()); maxWidth = Math.max(maxWidth, drawable.getMinimumWidth()); } setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec), resolveSize(maxHeight, heightMeasureSpec)); } private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx, float sy) { canvas.save(); canvas.translate(x, y); canvas.clipRect(0, 0, w, h); canvas.scale(0.5f, 0.5f); canvas.scale(sx, sy, w, h); canvas.drawPicture(mPicture); canvas.restore(); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight())); mPicture.endRecording(); int x = getWidth() / 2; int y = getHeight() / 2; if (false) { canvas.drawPicture(mPicture); } else { drawPict(canvas, 0, 0, x, y, 1, 1); drawPict(canvas, x, 0, x, y, -1, 1); drawPict(canvas, 0, y, x, y, 1, -1); drawPict(canvas, x, y, x, y, -1, -1); } } @Override public ViewParent invalidateChildInParent(int[] location, Rect dirty) { location[0] = getLeft(); location[1] = getTop(); dirty.set(0, 0, getWidth(), getHeight()); return getParent(); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = super.getChildCount(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final int childLeft = getPaddingLeft(); final int childTop = getPaddingTop(); child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); } } } }
package app.test; import java.io.ByteArrayOutputStream; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Picture; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; public class Test extends GraphicsActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new SampleView(this)); } private static final int WIDTH = 50; private static final int HEIGHT = 50; private static final int STRIDE = 64; // must be >= WIDTH private static int[] createColors() { int[] colors = new int[STRIDE * HEIGHT]; for (int y = 0; y < HEIGHT; y++) { for (int x = 0; x < WIDTH; x++) { int r = x * 255 / (WIDTH - 1); int g = y * 255 / (HEIGHT - 1); int b = 255 - Math.min(r, g); int a = Math.max(r, g); colors[y * STRIDE + x] = (a << 24) | (r << 16) | (g << 8) | b; } } return colors; } private static class SampleView extends View { private Bitmap[] mBitmaps; private Bitmap[] mJPEG; private Bitmap[] mPNG; private int[] mColors; private Paint mPaint; private static Bitmap codec(Bitmap src, Bitmap.CompressFormat format, int quality) { ByteArrayOutputStream os = new ByteArrayOutputStream(); src.compress(format, quality, os); byte[] array = os.toByteArray(); return BitmapFactory.decodeByteArray(array, 0, array.length); } public SampleView(Context context) { super(context); setFocusable(true); mColors = createColors(); int[] colors = mColors; mBitmaps = new Bitmap[6]; // these three are initialized with colors[] mBitmaps[0] = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT, Bitmap.Config.ARGB_8888); mBitmaps[1] = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT, Bitmap.Config.RGB_565); mBitmaps[2] = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT, Bitmap.Config.ARGB_4444); // these three will have their colors set later mBitmaps[3] = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888); mBitmaps[4] = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.RGB_565); mBitmaps[5] = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_4444); for (int i = 3; i <= 5; i++) { mBitmaps[i].setPixels(colors, 0, STRIDE, 0, 0, WIDTH, HEIGHT); } mPaint = new Paint(); mPaint.setDither(true); // now encode/decode using JPEG and PNG mJPEG = new Bitmap[mBitmaps.length]; mPNG = new Bitmap[mBitmaps.length]; for (int i = 0; i < mBitmaps.length; i++) { mJPEG[i] = codec(mBitmaps[i], Bitmap.CompressFormat.JPEG, 80); mPNG[i] = codec(mBitmaps[i], Bitmap.CompressFormat.PNG, 0); } } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(Color.WHITE); for (int i = 0; i < mBitmaps.length; i++) { canvas.drawBitmap(mBitmaps[i], 0, 0, null); canvas.drawBitmap(mJPEG[i], 80, 0, null); canvas.drawBitmap(mPNG[i], 160, 0, null); canvas.translate(0, mBitmaps[i].getHeight()); } // draw the color array directly, w/o craeting a bitmap object canvas.drawBitmap(mColors, 0, STRIDE, 0, 0, WIDTH, HEIGHT, true, null); canvas.translate(0, HEIGHT); canvas.drawBitmap(mColors, 0, STRIDE, 0, 0, WIDTH, HEIGHT, false, mPaint); } } } class GraphicsActivity extends Activity { // set to true to test Picture private static final boolean TEST_PICTURE = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void setContentView(View view) { if (TEST_PICTURE) { ViewGroup vg = new PictureLayout(this); vg.addView(view); view = vg; } super.setContentView(view); } } class PictureLayout extends ViewGroup { private final Picture mPicture = new Picture(); public PictureLayout(Context context) { super(context); } public PictureLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void addView(View child) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child); } @Override public void addView(View child, int index) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index); } @Override public void addView(View child, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, params); } @Override public void addView(View child, int index, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index, params); } @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int count = getChildCount(); int maxHeight = 0; int maxWidth = 0; for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { measureChild(child, widthMeasureSpec, heightMeasureSpec); } } maxWidth += getPaddingLeft() + getPaddingRight(); maxHeight += getPaddingTop() + getPaddingBottom(); Drawable drawable = getBackground(); if (drawable != null) { maxHeight = Math.max(maxHeight, drawable.getMinimumHeight()); maxWidth = Math.max(maxWidth, drawable.getMinimumWidth()); } setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec), resolveSize(maxHeight, heightMeasureSpec)); } private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx, float sy) { canvas.save(); canvas.translate(x, y); canvas.clipRect(0, 0, w, h); canvas.scale(0.5f, 0.5f); canvas.scale(sx, sy, w, h); canvas.drawPicture(mPicture); canvas.restore(); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight())); mPicture.endRecording(); int x = getWidth() / 2; int y = getHeight() / 2; if (false) { canvas.drawPicture(mPicture); } else { drawPict(canvas, 0, 0, x, y, 1, 1); drawPict(canvas, x, 0, x, y, -1, 1); drawPict(canvas, 0, y, x, y, 1, -1); drawPict(canvas, x, y, x, y, -1, -1); } } @Override public ViewParent invalidateChildInParent(int[] location, Rect dirty) { location[0] = getLeft(); location[1] = getTop(); dirty.set(0, 0, getWidth(), getHeight()); return getParent(); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = super.getChildCount(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final int childLeft = getPaddingLeft(); final int childTop = getPaddingTop(); child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); } } } }
Bitmap.Config.ARGB_8888,Bitmap.Config.RGB_565, Bitmap.Config.ARGB_4444
package app.test; import java.io.ByteArrayOutputStream; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Picture; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; public class Test extends GraphicsActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new SampleView(this)); } private static final int WIDTH = 50; private static final int HEIGHT = 50; private static final int STRIDE = 64; // must be >= WIDTH private static int[] createColors() { int[] colors = new int[STRIDE * HEIGHT]; for (int y = 0; y < HEIGHT; y++) { for (int x = 0; x < WIDTH; x++) { int r = x * 255 / (WIDTH - 1); int g = y * 255 / (HEIGHT - 1); int b = 255 - Math.min(r, g); int a = Math.max(r, g); colors[y * STRIDE + x] = (a << 24) | (r << 16) | (g << 8) | b; } } return colors; } private static class SampleView extends View { private Bitmap[] mBitmaps; private Bitmap[] mJPEG; private Bitmap[] mPNG; private int[] mColors; private Paint mPaint; private static Bitmap codec(Bitmap src, Bitmap.CompressFormat format, int quality) { ByteArrayOutputStream os = new ByteArrayOutputStream(); src.compress(format, quality, os); byte[] array = os.toByteArray(); return BitmapFactory.decodeByteArray(array, 0, array.length); } public SampleView(Context context) { super(context); setFocusable(true); mColors = createColors(); int[] colors = mColors; mBitmaps = new Bitmap[6]; // these three are initialized with colors[] mBitmaps[0] = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT, Bitmap.Config.ARGB_8888); mBitmaps[1] = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT, Bitmap.Config.RGB_565); mBitmaps[2] = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT, Bitmap.Config.ARGB_4444); // these three will have their colors set later mBitmaps[3] = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888); mBitmaps[4] = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.RGB_565); mBitmaps[5] = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_4444); for (int i = 3; i <= 5; i++) { mBitmaps[i].setPixels(colors, 0, STRIDE, 0, 0, WIDTH, HEIGHT); } mPaint = new Paint(); mPaint.setDither(true); // now encode/decode using JPEG and PNG mJPEG = new Bitmap[mBitmaps.length]; mPNG = new Bitmap[mBitmaps.length]; for (int i = 0; i < mBitmaps.length; i++) { mJPEG[i] = codec(mBitmaps[i], Bitmap.CompressFormat.JPEG, 80); mPNG[i] = codec(mBitmaps[i], Bitmap.CompressFormat.PNG, 0); } } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(Color.WHITE); for (int i = 0; i < mBitmaps.length; i++) { canvas.drawBitmap(mBitmaps[i], 0, 0, null); canvas.drawBitmap(mJPEG[i], 80, 0, null); canvas.drawBitmap(mPNG[i], 160, 0, null); canvas.translate(0, mBitmaps[i].getHeight()); } // draw the color array directly, w/o craeting a bitmap object canvas.drawBitmap(mColors, 0, STRIDE, 0, 0, WIDTH, HEIGHT, true, null); canvas.translate(0, HEIGHT); canvas.drawBitmap(mColors, 0, STRIDE, 0, 0, WIDTH, HEIGHT, false, mPaint); } } } class GraphicsActivity extends Activity { // set to true to test Picture private static final boolean TEST_PICTURE = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void setContentView(View view) { if (TEST_PICTURE) { ViewGroup vg = new PictureLayout(this); vg.addView(view); view = vg; } super.setContentView(view); } } class PictureLayout extends ViewGroup { private final Picture mPicture = new Picture(); public PictureLayout(Context context) { super(context); } public PictureLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void addView(View child) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child); } @Override public void addView(View child, int index) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index); } @Override public void addView(View child, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, params); } @Override public void addView(View child, int index, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index, params); } @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int count = getChildCount(); int maxHeight = 0; int maxWidth = 0; for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { measureChild(child, widthMeasureSpec, heightMeasureSpec); } } maxWidth += getPaddingLeft() + getPaddingRight(); maxHeight += getPaddingTop() + getPaddingBottom(); Drawable drawable = getBackground(); if (drawable != null) { maxHeight = Math.max(maxHeight, drawable.getMinimumHeight()); maxWidth = Math.max(maxWidth, drawable.getMinimumWidth()); } setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec), resolveSize(maxHeight, heightMeasureSpec)); } private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx, float sy) { canvas.save(); canvas.translate(x, y); canvas.clipRect(0, 0, w, h); canvas.scale(0.5f, 0.5f); canvas.scale(sx, sy, w, h); canvas.drawPicture(mPicture); canvas.restore(); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight())); mPicture.endRecording(); int x = getWidth() / 2; int y = getHeight() / 2; if (false) { canvas.drawPicture(mPicture); } else { drawPict(canvas, 0, 0, x, y, 1, 1); drawPict(canvas, x, 0, x, y, -1, 1); drawPict(canvas, 0, y, x, y, 1, -1); drawPict(canvas, x, y, x, y, -1, -1); } } @Override public ViewParent invalidateChildInParent(int[] location, Rect dirty) { location[0] = getLeft(); location[1] = getTop(); dirty.set(0, 0, getWidth(), getHeight()); return getParent(); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = super.getChildCount(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final int childLeft = getPaddingLeft(); final int childTop = getPaddingTop(); child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); } } } }
Purgeable Bitmap
package app.test; import java.io.ByteArrayOutputStream; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapFactory.Options; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Picture; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; /** * PurgeableBitmap demonstrates the effects of setting Bitmaps as being * purgeable. * * In the NonPurgeable case, an encoded bitstream is decoded to a different * Bitmap over and over again up to 200 times until out-of-memory occurs. In * contrast, the Purgeable case shows that the system can complete decoding the * encoded bitstream 200 times without hitting the out-of-memory case. */ public class Test extends GraphicsActivity { private PurgeableBitmapView mView; private final RefreshHandler mRedrawHandler = new RefreshHandler(); class RefreshHandler extends Handler { @Override public void handleMessage(Message msg) { int index = mView.update(this); if (index > 0) { showAlertDialog(getDialogMessage(true, index)); } else if (index < 0) { mView.invalidate(); showAlertDialog(getDialogMessage(false, -index)); } else { mView.invalidate(); } } public void sleep(long delayMillis) { this.removeMessages(0); sendMessageDelayed(obtainMessage(0), delayMillis); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mView = new PurgeableBitmapView(this, detectIfPurgeableRequest()); mRedrawHandler.sleep(0); setContentView(mView); } private boolean detectIfPurgeableRequest() { PackageManager pm = getPackageManager(); CharSequence labelSeq = null; try { ActivityInfo info = pm.getActivityInfo(this.getComponentName(), PackageManager.GET_META_DATA); labelSeq = info.loadLabel(pm); } catch (NameNotFoundException e) { e.printStackTrace(); return false; } String[] components = labelSeq.toString().split("/"); if (components[components.length - 1].equals("Purgeable")) { return true; } else { return false; } } private String getDialogMessage(boolean isOutOfMemory, int index) { StringBuilder sb = new StringBuilder(); if (isOutOfMemory) { sb.append("Out of memery occurs when the "); sb.append(index); sb.append("th Bitmap is decoded."); } else { sb.append("Complete decoding ").append(index) .append(" bitmaps without running out of memory."); } return sb.toString(); } private void showAlertDialog(String message) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(message) .setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { } }); AlertDialog alert = builder.create(); alert.show(); } } /** * PurgeableBitmapView works with PurgeableBitmap to demonstrate the effects of * setting Bitmaps as being purgeable. * * PurgeableBitmapView decodes an encoded bitstream to a Bitmap each time * update() is invoked(), and its onDraw() draws the Bitmap and a number to * screen. The number is used to indicate the number of Bitmaps that has been * decoded. */ class PurgeableBitmapView extends View { private final byte[] bitstream; private Bitmap mBitmap; private final int mArraySize = 200; private final Bitmap[] mBitmapArray = new Bitmap[mArraySize]; private final Options mOptions = new Options(); private static final int WIDTH = 150; private static final int HEIGHT = 450; private static final int STRIDE = 320; // must be >= WIDTH private int mDecodingCount = 0; private final Paint mPaint = new Paint(); private final int textSize = 32; private static int delay = 100; public PurgeableBitmapView(Context context, boolean isPurgeable) { super(context); setFocusable(true); mOptions.inPurgeable = isPurgeable; int[] colors = createColors(); Bitmap src = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT, Bitmap.Config.ARGB_8888); bitstream = generateBitstream(src, Bitmap.CompressFormat.JPEG, 80); mPaint.setTextSize(textSize); mPaint.setColor(Color.GRAY); } private int[] createColors() { int[] colors = new int[STRIDE * HEIGHT]; for (int y = 0; y < HEIGHT; y++) { for (int x = 0; x < WIDTH; x++) { int r = x * 255 / (WIDTH - 1); int g = y * 255 / (HEIGHT - 1); int b = 255 - Math.min(r, g); int a = Math.max(r, g); colors[y * STRIDE + x] = (a << 24) | (r << 16) | (g << 8) | b; } } return colors; } public int update(Test.RefreshHandler handler) { try { mBitmapArray[mDecodingCount] = BitmapFactory.decodeByteArray( bitstream, 0, bitstream.length, mOptions); mBitmap = mBitmapArray[mDecodingCount]; mDecodingCount++; if (mDecodingCount < mArraySize) { handler.sleep(delay); return 0; } else { return -mDecodingCount; } } catch (OutOfMemoryError error) { for (int i = 0; i < mDecodingCount; i++) { mBitmapArray[i].recycle(); } return mDecodingCount + 1; } } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(Color.WHITE); canvas.drawBitmap(mBitmap, 0, 0, null); canvas.drawText(String.valueOf(mDecodingCount), WIDTH / 2 - 20, HEIGHT / 2, mPaint); } private byte[] generateBitstream(Bitmap src, Bitmap.CompressFormat format, int quality) { ByteArrayOutputStream os = new ByteArrayOutputStream(); src.compress(format, quality, os); return os.toByteArray(); } } class GraphicsActivity extends Activity { // set to true to test Picture private static final boolean TEST_PICTURE = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void setContentView(View view) { if (TEST_PICTURE) { ViewGroup vg = new PictureLayout(this); vg.addView(view); view = vg; } super.setContentView(view); } } class PictureLayout extends ViewGroup { private final Picture mPicture = new Picture(); public PictureLayout(Context context) { super(context); } public PictureLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void addView(View child) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child); } @Override public void addView(View child, int index) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index); } @Override public void addView(View child, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, params); } @Override public void addView(View child, int index, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index, params); } @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int count = getChildCount(); int maxHeight = 0; int maxWidth = 0; for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { measureChild(child, widthMeasureSpec, heightMeasureSpec); } } maxWidth += getPaddingLeft() + getPaddingRight(); maxHeight += getPaddingTop() + getPaddingBottom(); Drawable drawable = getBackground(); if (drawable != null) { maxHeight = Math.max(maxHeight, drawable.getMinimumHeight()); maxWidth = Math.max(maxWidth, drawable.getMinimumWidth()); } setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec), resolveSize(maxHeight, heightMeasureSpec)); } private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx, float sy) { canvas.save(); canvas.translate(x, y); canvas.clipRect(0, 0, w, h); canvas.scale(0.5f, 0.5f); canvas.scale(sx, sy, w, h); canvas.drawPicture(mPicture); canvas.restore(); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight())); mPicture.endRecording(); int x = getWidth() / 2; int y = getHeight() / 2; if (false) { canvas.drawPicture(mPicture); } else { drawPict(canvas, 0, 0, x, y, 1, 1); drawPict(canvas, x, 0, x, y, -1, 1); drawPict(canvas, 0, y, x, y, 1, -1); drawPict(canvas, x, y, x, y, -1, -1); } } @Override public ViewParent invalidateChildInParent(int[] location, Rect dirty) { location[0] = getLeft(); location[1] = getTop(); dirty.set(0, 0, getWidth(), getHeight()); return getParent(); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = super.getChildCount(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final int childLeft = getPaddingLeft(); final int childTop = getPaddingTop(); child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); } } } }
Create a bitmap with a circle
package app.test; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Picture; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Shader; import android.graphics.Xfermode; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; public class Xfermodes extends GraphicsActivity { // create a bitmap with a circle, used for the "dst" image static Bitmap makeDst(int w, int h) { Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(bm); Paint p = new Paint(Paint.ANTI_ALIAS_FLAG); p.setColor(0xFFFFCC44); c.drawOval(new RectF(0, 0, w * 3 / 4, h * 3 / 4), p); return bm; } // create a bitmap with a rect, used for the "src" image static Bitmap makeSrc(int w, int h) { Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(bm); Paint p = new Paint(Paint.ANTI_ALIAS_FLAG); p.setColor(0xFF66AAFF); c.drawRect(w / 3, h / 3, w * 19 / 20, h * 19 / 20, p); return bm; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new SampleView(this)); } private static class SampleView extends View { private static final int W = 64; private static final int H = 64; private static final int ROW_MAX = 4; // number of samples per row private Bitmap mSrcB; private Bitmap mDstB; private Shader mBG; // background checker-board pattern private static final Xfermode[] sModes = { new PorterDuffXfermode(PorterDuff.Mode.CLEAR), new PorterDuffXfermode(PorterDuff.Mode.SRC), new PorterDuffXfermode(PorterDuff.Mode.DST), new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER), new PorterDuffXfermode(PorterDuff.Mode.DST_OVER), new PorterDuffXfermode(PorterDuff.Mode.SRC_IN), new PorterDuffXfermode(PorterDuff.Mode.DST_IN), new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT), new PorterDuffXfermode(PorterDuff.Mode.DST_OUT), new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP), new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP), new PorterDuffXfermode(PorterDuff.Mode.XOR), new PorterDuffXfermode(PorterDuff.Mode.DARKEN), new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN), new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY), new PorterDuffXfermode(PorterDuff.Mode.SCREEN) }; private static final String[] sLabels = { "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn", "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Darken", "Lighten", "Multiply", "Screen" }; public SampleView(Context context) { super(context); mSrcB = makeSrc(W, H); mDstB = makeDst(W, H); // make a ckeckerboard pattern Bitmap bm = Bitmap.createBitmap(new int[] { 0xFFFFFFFF, 0xFFCCCCCC, 0xFFCCCCCC, 0xFFFFFFFF }, 2, 2, Bitmap.Config.RGB_565); mBG = new BitmapShader(bm, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); Matrix m = new Matrix(); m.setScale(6, 6); mBG.setLocalMatrix(m); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(Color.WHITE); Paint labelP = new Paint(Paint.ANTI_ALIAS_FLAG); labelP.setTextAlign(Paint.Align.CENTER); Paint paint = new Paint(); paint.setFilterBitmap(false); canvas.translate(15, 35); int x = 0; int y = 0; for (int i = 0; i < sModes.length; i++) { // draw the border paint.setStyle(Paint.Style.STROKE); paint.setShader(null); canvas.drawRect(x - 0.5f, y - 0.5f, x + W + 0.5f, y + H + 0.5f, paint); // draw the checker-board pattern paint.setStyle(Paint.Style.FILL); paint.setShader(mBG); canvas.drawRect(x, y, x + W, y + H, paint); // draw the src/dst example into our offscreen bitmap int sc = canvas.saveLayer(x, y, x + W, y + H, null, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG); canvas.translate(x, y); canvas.drawBitmap(mDstB, 0, 0, paint); paint.setXfermode(sModes[i]); canvas.drawBitmap(mSrcB, 0, 0, paint); paint.setXfermode(null); canvas.restoreToCount(sc); // draw the label canvas.drawText(sLabels[i], x + W / 2, y - labelP.getTextSize() / 2, labelP); x += W + 10; // wrap around when we've drawn enough for one row if ((i % ROW_MAX) == ROW_MAX - 1) { x = 0; y += H + 30; } } } } } class GraphicsActivity extends Activity { // set to true to test Picture private static final boolean TEST_PICTURE = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void setContentView(View view) { if (TEST_PICTURE) { ViewGroup vg = new PictureLayout(this); vg.addView(view); view = vg; } super.setContentView(view); } } class PictureLayout extends ViewGroup { private final Picture mPicture = new Picture(); public PictureLayout(Context context) { super(context); } public PictureLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void addView(View child) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child); } @Override public void addView(View child, int index) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index); } @Override public void addView(View child, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, params); } @Override public void addView(View child, int index, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index, params); } @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int count = getChildCount(); int maxHeight = 0; int maxWidth = 0; for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { measureChild(child, widthMeasureSpec, heightMeasureSpec); } } maxWidth += getPaddingLeft() + getPaddingRight(); maxHeight += getPaddingTop() + getPaddingBottom(); Drawable drawable = getBackground(); if (drawable != null) { maxHeight = Math.max(maxHeight, drawable.getMinimumHeight()); maxWidth = Math.max(maxWidth, drawable.getMinimumWidth()); } setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec), resolveSize(maxHeight, heightMeasureSpec)); } private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx, float sy) { canvas.save(); canvas.translate(x, y); canvas.clipRect(0, 0, w, h); canvas.scale(0.5f, 0.5f); canvas.scale(sx, sy, w, h); canvas.drawPicture(mPicture); canvas.restore(); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight())); mPicture.endRecording(); int x = getWidth() / 2; int y = getHeight() / 2; if (false) { canvas.drawPicture(mPicture); } else { drawPict(canvas, 0, 0, x, y, 1, 1); drawPict(canvas, x, 0, x, y, -1, 1); drawPict(canvas, 0, y, x, y, 1, -1); drawPict(canvas, x, y, x, y, -1, -1); } } @Override public ViewParent invalidateChildInParent(int[] location, Rect dirty) { location[0] = getLeft(); location[1] = getTop(); dirty.set(0, 0, getWidth(), getHeight()); return getParent(); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = super.getChildCount(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final int childLeft = getPaddingLeft(); final int childTop = getPaddingTop(); child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); } } } }
package app.test; import android.app.Activity; import android.os.Bundle; import android.graphics.BitmapFactory; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.ScrollView; import android.view.LayoutInflater; import android.view.View; import android.content.Context; import android.util.DisplayMetrics; import android.util.Log; /** * This activity demonstrates various ways density can cause the scaling of * bitmaps and drawables. */ public class DensityActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final LayoutInflater li = (LayoutInflater)getSystemService( LAYOUT_INFLATER_SERVICE); this.setTitle("density_title"); LinearLayout root = new LinearLayout(this); root.setOrientation(LinearLayout.VERTICAL); LinearLayout layout = new LinearLayout(this); addBitmapDrawable(layout, R.drawable.logo120dpi, true); addBitmapDrawable(layout, R.drawable.logo160dpi, true); addBitmapDrawable(layout, R.drawable.logo240dpi, true); addLabelToRoot(root, "Prescaled bitmap in drawable"); addChildToRoot(root, layout); layout = new LinearLayout(this); addBitmapDrawable(layout, R.drawable.logo120dpi, false); addBitmapDrawable(layout, R.drawable.logo160dpi, false); addBitmapDrawable(layout, R.drawable.logo240dpi, false); addLabelToRoot(root, "Autoscaled bitmap in drawable"); addChildToRoot(root, layout); layout = new LinearLayout(this); addResourceDrawable(layout, R.drawable.logo120dpi); addResourceDrawable(layout, R.drawable.logo160dpi); addResourceDrawable(layout, R.drawable.logo240dpi); addLabelToRoot(root, "Prescaled resource drawable"); addChildToRoot(root, layout); layout = (LinearLayout)li.inflate(R.layout.density_image_views, null); addLabelToRoot(root, "Inflated layout"); addChildToRoot(root, layout); layout = (LinearLayout)li.inflate(R.layout.density_styled_image_views, null); addLabelToRoot(root, "Inflated styled layout"); addChildToRoot(root, layout); layout = new LinearLayout(this); addCanvasBitmap(layout, R.drawable.logo120dpi, true); addCanvasBitmap(layout, R.drawable.logo160dpi, true); addCanvasBitmap(layout, R.drawable.logo240dpi, true); addLabelToRoot(root, "Prescaled bitmap"); addChildToRoot(root, layout); layout = new LinearLayout(this); addCanvasBitmap(layout, R.drawable.logo120dpi, false); addCanvasBitmap(layout, R.drawable.logo160dpi, false); addCanvasBitmap(layout, R.drawable.logo240dpi, false); addLabelToRoot(root, "Autoscaled bitmap"); addChildToRoot(root, layout); layout = new LinearLayout(this); addResourceDrawable(layout, R.drawable.logonodpi120); addResourceDrawable(layout, R.drawable.logonodpi160); addResourceDrawable(layout, R.drawable.logonodpi240); addLabelToRoot(root, "No-dpi resource drawable"); addChildToRoot(root, layout); layout = new LinearLayout(this); addNinePatchResourceDrawable(layout, R.drawable.smlnpatch120dpi); addNinePatchResourceDrawable(layout, R.drawable.smlnpatch160dpi); addNinePatchResourceDrawable(layout, R.drawable.smlnpatch240dpi); addLabelToRoot(root, "Prescaled 9-patch resource drawable"); addChildToRoot(root, layout); setContentView(scrollWrap(root)); } private View scrollWrap(View view) { ScrollView scroller = new ScrollView(this); scroller.addView(view, new ScrollView.LayoutParams(ScrollView.LayoutParams.MATCH_PARENT, ScrollView.LayoutParams.MATCH_PARENT)); return scroller; } private void addLabelToRoot(LinearLayout root, String text) { TextView label = new TextView(this); label.setText(text); root.addView(label, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); } private void addChildToRoot(LinearLayout root, LinearLayout layout) { root.addView(layout, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); } private void addBitmapDrawable(LinearLayout layout, int resource, boolean scale) { Bitmap bitmap; bitmap = loadAndPrintDpi(resource, scale); View view = new View(this); final BitmapDrawable d = new BitmapDrawable(getResources(), bitmap); if (!scale) d.setTargetDensity(getResources().getDisplayMetrics()); view.setBackgroundDrawable(d); view.setLayoutParams(new LinearLayout.LayoutParams(d.getIntrinsicWidth(), d.getIntrinsicHeight())); layout.addView(view); } private void addResourceDrawable(LinearLayout layout, int resource) { View view = new View(this); final Drawable d = getResources().getDrawable(resource); view.setBackgroundDrawable(d); view.setLayoutParams(new LinearLayout.LayoutParams(d.getIntrinsicWidth(), d.getIntrinsicHeight())); layout.addView(view); } private void addCanvasBitmap(LinearLayout layout, int resource, boolean scale) { Bitmap bitmap; bitmap = loadAndPrintDpi(resource, scale); ScaledBitmapView view = new ScaledBitmapView(this, bitmap); view.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)); layout.addView(view); } private void addNinePatchResourceDrawable(LinearLayout layout, int resource) { View view = new View(this); final Drawable d = getResources().getDrawable(resource); view.setBackgroundDrawable(d); Log.i("foo", "9-patch #" + Integer.toHexString(resource) + " w=" + d.getIntrinsicWidth() + " h=" + d.getIntrinsicHeight()); view.setLayoutParams(new LinearLayout.LayoutParams( d.getIntrinsicWidth()*2, d.getIntrinsicHeight()*2)); layout.addView(view); } private Bitmap loadAndPrintDpi(int id, boolean scale) { Bitmap bitmap; if (scale) { bitmap = BitmapFactory.decodeResource(getResources(), id); } else { BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inScaled = false; bitmap = BitmapFactory.decodeResource(getResources(), id, opts); } return bitmap; } private class ScaledBitmapView extends View { private Bitmap mBitmap; public ScaledBitmapView(Context context, Bitmap bitmap) { super(context); mBitmap = bitmap; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); final DisplayMetrics metrics = getResources().getDisplayMetrics(); setMeasuredDimension( mBitmap.getScaledWidth(metrics), mBitmap.getScaledHeight(metrics)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawBitmap(mBitmap, 0.0f, 0.0f, null); } } } //layout/density_image_views.xml <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2009 The Android Open Source Project 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. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView style="@style/ImageView120dpi" /> <ImageView style="@style/ImageView160dpi" /> <ImageView style="@style/ImageView240dpi" /> </LinearLayout> //layout/density_styled_image_views <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2009 The Android Open Source Project 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. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/reslogo120dpi" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/reslogo160dpi" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/reslogo240dpi" /> </LinearLayout>
package app.test; import java.io.IOException; import android.app.Activity; import android.app.WallpaperManager; import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; /** * <h3>SetWallpaper Activity</h3> * * <p>This demonstrates the how to write an activity that gets the current system wallpaper, * modifies it and sets the modified bitmap as system wallpaper.</p> */ public class Test extends Activity { final static private int[] mColors = {Color.BLUE, Color.GREEN, Color.RED, Color.LTGRAY, Color.MAGENTA, Color.CYAN, Color.YELLOW, Color.WHITE}; /** * Initialization of the Activity after it is first created. Must at least * call {@link android.app.Activity#setContentView setContentView()} to * describe what is to be displayed in the screen. */ @Override protected void onCreate(Bundle savedInstanceState) { // Be sure to call the super class. super.onCreate(savedInstanceState); // See res/layout/wallpaper_2.xml for this // view layout definition, which is being set here as // the content of our screen. setContentView(R.layout.main); final WallpaperManager wallpaperManager = WallpaperManager.getInstance(this); final Drawable wallpaperDrawable = wallpaperManager.getDrawable(); final ImageView imageView = (ImageView) findViewById(R.id.imageview); imageView.setDrawingCacheEnabled(true); imageView.setImageDrawable(wallpaperDrawable); Button randomize = (Button) findViewById(R.id.randomize); randomize.setOnClickListener(new OnClickListener() { public void onClick(View view) { int mColor = (int) Math.floor(Math.random() * mColors.length); wallpaperDrawable.setColorFilter(mColors[mColor], PorterDuff.Mode.MULTIPLY); imageView.setImageDrawable(wallpaperDrawable); imageView.invalidate(); } }); Button setWallpaper = (Button) findViewById(R.id.setwallpaper); setWallpaper.setOnClickListener(new OnClickListener() { public void onClick(View view) { try { wallpaperManager.setBitmap(imageView.getDrawingCache()); finish(); } catch (IOException e) { e.printStackTrace(); } } }); } } //main.xml <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageview" /> <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="match_parent"> <Button android:id="@+id/randomize" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="randomize" android:layout_gravity="bottom" /> <Button android:id="@+id/setwallpaper" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="set_wallpaper" android:layout_gravity="bottom" /> </LinearLayout> </FrameLayout>
Bitmap cache by WeakHashMap
import java.util.WeakHashMap; import android.graphics.Bitmap; public class ImageCache extends WeakHashMap<String, Bitmap> { private static final long serialVersionUID = 1L; public boolean isCached(String url){ return containsKey(url) && get(url) != null; } }
Memory Cache for Bitmap
//package com.mediaportal.ampdroid.lists; import java.lang.ref.SoftReference; import java.util.HashMap; import android.graphics.Bitmap; public class MemoryCache { private HashMap<String, SoftReference<Bitmap>> cache=new HashMap<String, SoftReference<Bitmap>>(); public Bitmap get(String id){ if(!cache.containsKey(id)) return null; SoftReference<Bitmap> ref=cache.get(id); return ref.get(); } public boolean containsKey(String id){ return cache.containsKey(id); } public void put(String id, Bitmap bitmap){ cache.put(id, new SoftReference<Bitmap>(bitmap)); } public void clear() { cache.clear(); } }
Load Bitmap from resource
//package com.akjava.lib.android.ui; import java.io.BufferedInputStream; import java.io.InputStream; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.widget.Button; import android.widget.EditText; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.TextView; class WidgetUtil { public static Bitmap loadBitmap(Class clazz,String resouceName){ InputStream input=clazz.getResourceAsStream(resouceName); Bitmap bitmap=BitmapFactory.decodeStream(new BufferedInputStream(input,1024*8)); return bitmap; } }
Crop Bitmap
//package com.akjava.lib.android.image; import java.io.FileNotFoundException; import java.io.FileOutputStream; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory.Options; import android.util.Log; /** * * @author aki * @version 1.0 * ????????????? * ???????????????? * */ class ImageUtils { public static final String[] imageExtensions={"jpg","png","jpeg","gif"}; private ImageUtils(){} /** * ???????????????????????????????????????? * ???????????????? * * @param baseImage ??? * @param width ?? * @param height ?? * @return ????????????????? */ public static Bitmap fitImageNoMargin(Bitmap baseImage,int width,int height){ Point pt=calculateFitImage(baseImage,width,height,null);//TODO gc free Bitmap resizedBitmap = Bitmap.createScaledBitmap(baseImage, pt.x, pt.y, true); return resizedBitmap; } /** * ?????????????????????????????????? * ????????????????? * ?????????????????????? * * @param path * @param width * @param config * @return */ public static Bitmap sampleSizeOpenBitmapByWidth(String path,int width,Bitmap.Config config){ Point size=parseJpegSize(path, null); int rw=size.x/width; int sampleSize=Math.max(rw, 1); Bitmap bitmap=sampleSizeOpenBitmap(path, sampleSize); return bitmap; } /** * ?????????????????????????? * * * @param path * @param width * @param height * @param config null????Bitmap.Config.RGB_565?????? * @return ????????????????????????????? */ public static Bitmap fitImage(String path,int width,int height,Bitmap.Config config){ //TODO set bgcolor Point size=parseJpegSize(path, null); int rw=size.x/width; int rh=size.y/height; int sampleSize=Math.min(rw, rh); sampleSize=Math.max(sampleSize, 1); Bitmap bitmap=sampleSizeOpenBitmap(path, sampleSize,config); return fitImage(bitmap, width, height, config, true); } /** * ???????????? * * @param baseImage * @param width * @param height * @param config null????Bitmap.Config.RGB_565?????? * @param doRecycleBase ???bitmap?recycle???????true?? * @return ????????????????????????????? */ public static Bitmap fitImage(Bitmap baseImage,int width,int height,Bitmap.Config config,boolean doRecycleBase){ if(baseImage==null){ throw new RuntimeException("baseImage is null"); } if(config==null){ config=Bitmap.Config.RGB_565; } Point resizedP=calculateFitImage(baseImage, width, height, null);//TODO gc free Bitmap resizedBitmap = Bitmap.createScaledBitmap(baseImage, resizedP.x, resizedP.y, true); if(doRecycleBase){//to avoid memory error baseImage.recycle(); } Bitmap returnBitmap=Bitmap.createBitmap(width, height, config); Canvas canvas=new Canvas(returnBitmap); canvas.drawBitmap(resizedBitmap, (width-resizedP.x)/2, (height-resizedP.y)/2,null); resizedBitmap.recycle(); return returnBitmap; } /** * ???????????????????????????? * * @param baseImage * @param width * @param height * @param receiver * @return */ public static Point calculateFitImage(Bitmap baseImage,int width,int height,Point receiver){ if(baseImage==null){ throw new RuntimeException("baseImage is null"); } if(receiver==null){ receiver=new Point(); } int dw=width; int dh=height; if(dw!=0 && dh!=0 ){ double waspect=(double)dw/baseImage.getWidth(); double haspect=(double)dh/baseImage.getHeight(); if(waspect>haspect){//fit h dw=(int) (baseImage.getWidth()*haspect); }else{ dh=(int)(baseImage.getHeight()*waspect); } } receiver.x=dw; receiver.y=dh; return receiver; } /** * ????????????????????recyle????? * * @param baseImage * @param width * @param height * @return */ public static Bitmap toTextureImage(Bitmap baseImage,int width,int height){ return toTextureImage(baseImage, width, height,false); } /** * PNG ?????????? * * @param bitmap * @param output * @return * @throws FileNotFoundException */ public static boolean writeAsPng(Bitmap bitmap,String output) throws FileNotFoundException{ return bitmap.compress(Bitmap.CompressFormat.PNG, 1, new FileOutputStream(output)); } /** * ??????????????? * * @param baseImage * @param width must be divided 2 (like 256 or 512) * @param height must be divided 2 (like 256 or 512) * @return */ public static Bitmap toTextureImage(Bitmap baseImage,int width,int height,boolean recycle){ int owidth = baseImage.getWidth(); int oheight = baseImage.getHeight(); // calculate the scale - in this case = 0.4f float scaleWidth = ((float) width) / owidth; float scaleHeight = ((float) height) / oheight; Matrix matrix = new Matrix(); // resize the bit map matrix.postScale(scaleWidth, -scaleHeight); // rotate the Bitmap //matrix.postRotate(-180); Bitmap resizedBitmap = Bitmap.createBitmap(baseImage, 0, 0, owidth, oheight, matrix, true); if(recycle){ baseImage.recycle(); } Log.i("myapp","resized:"+resizedBitmap.getWidth()+"x"+resizedBitmap.getHeight()); return resizedBitmap; } /** * ????????????????????????? * * @param baseImage * @param width * @param height * @param rotateRight * @return */ public static Bitmap toRotateTextureImage(Bitmap baseImage,int width,int height,boolean rotateRight){ int owidth = baseImage.getWidth(); int oheight = baseImage.getHeight(); // calculate the scale - in this case = 0.4f float scaleWidth = ((float) width) / owidth; float scaleHeight = ((float) height) / oheight; Matrix matrix = new Matrix(); // resize the bit map matrix.postScale(scaleWidth, -scaleHeight); // rotate the Bitmap if(rotateRight){ matrix.postRotate(90); }else{ matrix.postRotate(-90); } Bitmap resizedBitmap = Bitmap.createBitmap(baseImage, 0, 0, owidth, oheight, matrix, true); Log.i("myapp","resized:"+resizedBitmap.getWidth()+"x"+resizedBitmap.getHeight()); return resizedBitmap; } /** * ???????????sampleSize???????width?height?????????? */ public static int lastSampleSize=1; //public static BitmapFactory.Options bitmapOption;//cancel????????denger /** * ????????????????????? * ??????????????????????????????????????? * * @param path * @param startSize * @param config * @return */ public static Bitmap sampleSizeOpenBitmap(String path, int startSize, Config config) { BitmapFactory.Options bitmapOption = new BitmapFactory.Options(); bitmapOption.inPreferredConfig=config; return sampleSizeOpenBitmap(path, startSize,bitmapOption); } /** * ????????????????????? * ??????????????????????????????????????? * * @param path * @param startSize * @param bitmapOption * @return */ public static Bitmap sampleSizeOpenBitmap(String path, int startSize, Options bitmapOption) { int inSampleSize=startSize; Bitmap bitmap=null; for(int i=0;i<10;i++){ try{ bitmapOption.inSampleSize=inSampleSize; bitmap=BitmapFactory.decodeFile(path,bitmapOption); //Log.i("imageutils","decoded bitmap:"+bitmapOption.inSampleSize); lastSampleSize=inSampleSize; if(bitmap==null){ System.gc();//ready for next } }catch(Error e){ Log.i("imageutils","faild load:"+inSampleSize+" "+path); } if(bitmap!=null || bitmapOption.mCancel){ break; }else{ //inSampleSize*=2; inSampleSize+=1; } } return bitmap; } /** * ?????????????????????? * * @param path * @param width * @param height * @param config * @return */ public static Bitmap sampleSizeOpenBitmap(String path,int width,int height,Config config){ Point size=parseJpegSize(path, null); int rw=size.x/width; int rh=size.y/height; int sampleSize=Math.min(rw, rh); sampleSize=Math.max(sampleSize, 1); return sampleSizeOpenBitmap(path, sampleSize,config); } /** * MemoryError????????????Content://???????? * ???? RGB565????? * @see MediaImageUtils#loadImageFileOrUri(android.content.ContentResolver, String) * @param path * @param startSize * @return */ public static Bitmap sampleSizeOpenBitmap(String path,int startSize){ return sampleSizeOpenBitmap(path, startSize,(Config) null); } /** * ???????????????????? * @param name * @return */ public static boolean isImageFile(String name){ for (int i = 0; i < imageExtensions.length; i++) { if(name.toLowerCase().endsWith("."+imageExtensions[i])) { return true; } } return false; } /** * ????????? * * @param bitmap * @param rect * @return */ public static Bitmap cropBitmap(Bitmap bitmap,Rect rect){ int w=rect.right-rect.left; int h=rect.bottom-rect.top; Bitmap ret=Bitmap.createBitmap(w, h, bitmap.getConfig()); Canvas canvas=new Canvas(ret); canvas.drawBitmap(bitmap, -rect.left, -rect.top, null); return ret; } /** * JPEG??????????? * * @param path * @param receiver * @return */ public static Point parseJpegSize(String path,Point receiver){ if(receiver==null){ receiver=new Point(); } Options option=new BitmapFactory.Options(); option.inJustDecodeBounds=true; BitmapFactory.decodeFile(path,option); receiver.x=option.outWidth; receiver.y=option.outHeight; return receiver; } }
Create Scaled Bitmap
//package org.ametro.util; import android.graphics.Bitmap; import android.graphics.BitmapFactory; class BitmapUtil { public static Bitmap createScaledBitmap(String path, float scale, boolean filtering){ Bitmap src = BitmapFactory.decodeFile(path); int width = (int)( src.getWidth() * scale + 0.5f); int height = (int)( src.getHeight() * scale + 0.5f); return Bitmap.createScaledBitmap(src, width, height, filtering); } }
downloading a bitmap image from http and setting it to given image view asynchronously
//package org.andlib.helpers; import java.io.InputStream; import java.lang.ref.WeakReference; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.methods.HttpGet; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.http.AndroidHttpClient; import android.os.AsyncTask; import android.widget.ImageView; class AsyncImageDownloadTask extends AsyncTask<String, Void, Bitmap> { private String url; private final WeakReference<ImageView> imageViewReference; private ImageDownloadListener listener; /** * * @param imageView */ public AsyncImageDownloadTask(ImageView imageView, ImageDownloadListener listener) { imageViewReference = new WeakReference<ImageView>(imageView); this.listener = listener; } /** * * @param url * @param imageView */ public void download(String url, ImageView imageView) { if(cancelPotentialDownload(url, imageView)) { AsyncImageDownloadTask task = new AsyncImageDownloadTask(imageView, listener); DownloadedDrawable downloadedDrawable = new DownloadedDrawable(task); imageView.setImageDrawable(downloadedDrawable); task.execute(url); } } @Override protected Bitmap doInBackground(String... params) { return downloadBitmap(params[0]); } @Override protected void onPostExecute(Bitmap bitmap) { if(isCancelled()) { bitmap = null; } if(imageViewReference != null) { ImageView imageView = imageViewReference.get(); AsyncImageDownloadTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView); // Change bitmap only if this process is still associated with it if(this == bitmapDownloaderTask) { imageView.setImageBitmap(bitmap); } } } /** * * @param url * @param imageView * @return false if the same url is already being downloaded */ private boolean cancelPotentialDownload(String url, ImageView imageView) { AsyncImageDownloadTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView); if(bitmapDownloaderTask != null) { String bitmapUrl = bitmapDownloaderTask.url; if(bitmapUrl == null || !bitmapUrl.equals(url)) { bitmapDownloaderTask.cancel(true); } else { return false; } } return true; } /** * * @param url * @return */ private Bitmap downloadBitmap(String url) { final AndroidHttpClient client = AndroidHttpClient.newInstance("Android"); final HttpGet getRequest = new HttpGet(url); try { HttpResponse response = client.execute(getRequest); final int statusCode = response.getStatusLine().getStatusCode(); if(statusCode == HttpStatus.SC_OK) { final HttpEntity entity = response.getEntity(); if(entity != null) { InputStream inputStream = null; try { inputStream = entity.getContent(); final Bitmap bitmap = BitmapFactory.decodeStream(inputStream); if(listener != null) listener.imageDownloaded(url, bitmap); //call back return bitmap; } finally { if(inputStream != null) { inputStream.close(); } entity.consumeContent(); } } } } catch(Exception e) { // Could provide a more explicit error message for IOException or // IllegalStateException getRequest.abort(); } finally { if(client != null) { client.close(); } } if(listener != null) listener.imageDownloadFailed(url); //call back return null; } /** * * @param imageView * @return */ private AsyncImageDownloadTask getBitmapDownloaderTask(ImageView imageView) { if(imageView != null) { Drawable drawable = imageView.getDrawable(); if(drawable instanceof DownloadedDrawable) { DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable; return downloadedDrawable.getBitmapDownloaderTask(); } } return null; } /** * <b>referenced</b>: http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html * */ private class DownloadedDrawable extends ColorDrawable { private final WeakReference<AsyncImageDownloadTask> bitmapDownloaderTaskReference; public DownloadedDrawable(AsyncImageDownloadTask bitmapDownloaderTask) { super(Color.BLACK); bitmapDownloaderTaskReference = new WeakReference<AsyncImageDownloadTask>(bitmapDownloaderTask); } public AsyncImageDownloadTask getBitmapDownloaderTask() { return bitmapDownloaderTaskReference.get(); } } /** * for calling back download results * * @author meinside@gmail.com * */ public interface ImageDownloadListener { /** * called when the download failed * * @param imageUrl */ public void imageDownloadFailed(String imageUrl); /** * called when the download finished successfully * * @param imageUrl * @param downloadedImage */ public void imageDownloaded(String imageUrl, Bitmap downloadedImage); } }
Get Bitmap From Local Path
//package org.andlib.helpers.image; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Map; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.hardware.Camera.Size; import android.view.View; final class ImageUtility { public static final int READ_BUFFER_SIZE = 32 * 1024; //32KB /** * * @param path * @param sampleSize 1 = 100%, 2 = 50%(1/2), 4 = 25%(1/4), ... * @return */ public static Bitmap getBitmapFromLocalPath(String path, int sampleSize) { try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = sampleSize; return BitmapFactory.decodeFile(path, options); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param bytes * @return */ public static Bitmap getBitmapFromBytes(byte[] bytes) { try { return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param bitmap * @param quality 1 ~ 100 * @return */ public static byte[] compressBitmap(Bitmap bitmap, int quality) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, quality, baos); return baos.toByteArray(); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param srcBitmap * @param newWidth * @param newHeight * @return */ public static Bitmap getResizedBitmap(Bitmap srcBitmap, int newWidth, int newHeight) { try { return Bitmap.createScaledBitmap(srcBitmap, newWidth, newHeight, true); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * captures given view and converts it to a bitmap * @param view * @return */ public static Bitmap captureViewToBitmap(View view) { Bitmap result = null; try { result = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.RGB_565); view.draw(new Canvas(result)); } catch(Exception e) { //Logger.e(e.toString()); } return result; } /** * * @param original * @param format * @param quality * @param outputLocation * @return */ public static boolean saveBitmap(Bitmap original, Bitmap.CompressFormat format, int quality, String outputLocation) { if(original == null) return false; try { return original.compress(format, quality, new FileOutputStream(outputLocation)); } catch(Exception e) { // Logger.e(e.toString()); } return false; } /** * * @param filepath * @param widthLimit * @param heightLimit * @param totalSize * @return */ public static Bitmap getResizedBitmap(String filepath, int widthLimit, int heightLimit, int totalSize) { int outWidth = 0; int outHeight = 0; int resize = 1; InputStream input = null; try { input = new FileInputStream(new File(filepath)); BitmapFactory.Options getSizeOpt = new BitmapFactory.Options(); getSizeOpt.inJustDecodeBounds = true; BitmapFactory.decodeStream(input, null, getSizeOpt); outWidth = getSizeOpt.outWidth; outHeight = getSizeOpt.outHeight; while((outWidth / resize) > widthLimit || (outHeight / resize) > heightLimit) { resize *= 2; } resize = resize * (totalSize + 15) / 15; BitmapFactory.Options resizeOpt = new BitmapFactory.Options(); resizeOpt.inSampleSize = resize; input.close(); input = null; input = new FileInputStream(new File(filepath)); Bitmap bitmapImage = BitmapFactory.decodeStream(input, null, resizeOpt); return bitmapImage; } catch(Exception e) { // Logger.e(e.toString()); } finally { if(input != null) { try { input.close(); } catch(IOException e) { // Logger.e(e.toString()); } } } return null; } /** * generate a blurred bitmap from given one * * referenced: http://incubator.quasimondo.com/processing/superfastblur.pde * * @param original * @param radius * @return */ public Bitmap getBlurredBitmap(Bitmap original, int radius) { if (radius < 1) return null; int width = original.getWidth(); int height = original.getHeight(); int wm = width - 1; int hm = height - 1; int wh = width * height; int div = radius + radius + 1; int r[] = new int[wh]; int g[] = new int[wh]; int b[] = new int[wh]; int rsum, gsum, bsum, x, y, i, p, p1, p2, yp, yi, yw; int vmin[] = new int[Math.max(width, height)]; int vmax[] = new int[Math.max(width,height)]; int dv[] = new int[256 * div]; for (i=0; i<256*div; i++) dv[i] = i / div; int[] blurredBitmap = new int[wh]; original.getPixels(blurredBitmap, 0, width, 0, 0, width, height); yw = 0; yi = 0; for (y=0; y<height; y++) { rsum = 0; gsum = 0; bsum = 0; for(i=-radius; i<=radius; i++) { p = blurredBitmap[yi + Math.min(wm, Math.max(i,0))]; rsum += (p & 0xff0000) >> 16; gsum += (p & 0x00ff00) >> 8; bsum += p & 0x0000ff; } for (x=0; x<width; x++) { r[yi] = dv[rsum]; g[yi] = dv[gsum]; b[yi] = dv[bsum]; if(y==0) { vmin[x] = Math.min(x + radius+1,wm); vmax[x] = Math.max(x - radius,0); } p1 = blurredBitmap[yw + vmin[x]]; p2 = blurredBitmap[yw + vmax[x]]; rsum += ((p1 & 0xff0000)-(p2 & 0xff0000))>>16; gsum += ((p1 & 0x00ff00)-(p2 & 0x00ff00))>>8; bsum += (p1 & 0x0000ff)-(p2 & 0x0000ff); yi ++; } yw += width; } for (x=0; x<width; x++) { rsum=gsum=bsum=0; yp =- radius * width; for(i=-radius; i<=radius; i++) { yi = Math.max(0,yp) + x; rsum += r[yi]; gsum += g[yi]; bsum += b[yi]; yp += width; } yi = x; for (y=0; y<height; y++) { blurredBitmap[yi] = 0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum]; if(x == 0) { vmin[y] = Math.min(y + radius + 1, hm) * width; vmax[y] = Math.max(y - radius, 0) * width; } p1 = x + vmin[y]; p2 = x + vmax[y]; rsum += r[p1] - r[p2]; gsum += g[p1] - g[p2]; bsum += b[p1] - b[p2]; yi += width; } } return Bitmap.createBitmap(blurredBitmap, width, height, Bitmap.Config.RGB_565); } /** * calculate optimal preview size from given parameters * <br> * referenced: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html * * @param sizes obtained from camera.getParameters().getSupportedPreviewSizes() * @param w * @param h * @return */ public static Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.05; double targetRatio = (double) w / h; if (sizes == null) return null; Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; // Try to find an size match aspect ratio and size for (Size size : sizes) { double ratio = (double) size.width / size.height; if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } // Cannot find the one match the aspect ratio, ignore the requirement if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } return optimalSize; } }
Get Bitmap From Bytes
//package org.andlib.helpers.image; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Map; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.hardware.Camera.Size; import android.view.View; /** * * @author meinside@gmail.com * @since 09.10.12. * * last update 10.11.05. * */ final class ImageUtility { public static final int READ_BUFFER_SIZE = 32 * 1024; //32KB /** * * @param path * @param sampleSize 1 = 100%, 2 = 50%(1/2), 4 = 25%(1/4), ... * @return */ public static Bitmap getBitmapFromLocalPath(String path, int sampleSize) { try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = sampleSize; return BitmapFactory.decodeFile(path, options); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param bytes * @return */ public static Bitmap getBitmapFromBytes(byte[] bytes) { try { return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param bitmap * @param quality 1 ~ 100 * @return */ public static byte[] compressBitmap(Bitmap bitmap, int quality) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, quality, baos); return baos.toByteArray(); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param srcBitmap * @param newWidth * @param newHeight * @return */ public static Bitmap getResizedBitmap(Bitmap srcBitmap, int newWidth, int newHeight) { try { return Bitmap.createScaledBitmap(srcBitmap, newWidth, newHeight, true); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * captures given view and converts it to a bitmap * @param view * @return */ public static Bitmap captureViewToBitmap(View view) { Bitmap result = null; try { result = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.RGB_565); view.draw(new Canvas(result)); } catch(Exception e) { //Logger.e(e.toString()); } return result; } /** * * @param original * @param format * @param quality * @param outputLocation * @return */ public static boolean saveBitmap(Bitmap original, Bitmap.CompressFormat format, int quality, String outputLocation) { if(original == null) return false; try { return original.compress(format, quality, new FileOutputStream(outputLocation)); } catch(Exception e) { // Logger.e(e.toString()); } return false; } /** * * @param filepath * @param widthLimit * @param heightLimit * @param totalSize * @return */ public static Bitmap getResizedBitmap(String filepath, int widthLimit, int heightLimit, int totalSize) { int outWidth = 0; int outHeight = 0; int resize = 1; InputStream input = null; try { input = new FileInputStream(new File(filepath)); BitmapFactory.Options getSizeOpt = new BitmapFactory.Options(); getSizeOpt.inJustDecodeBounds = true; BitmapFactory.decodeStream(input, null, getSizeOpt); outWidth = getSizeOpt.outWidth; outHeight = getSizeOpt.outHeight; while((outWidth / resize) > widthLimit || (outHeight / resize) > heightLimit) { resize *= 2; } resize = resize * (totalSize + 15) / 15; BitmapFactory.Options resizeOpt = new BitmapFactory.Options(); resizeOpt.inSampleSize = resize; input.close(); input = null; input = new FileInputStream(new File(filepath)); Bitmap bitmapImage = BitmapFactory.decodeStream(input, null, resizeOpt); return bitmapImage; } catch(Exception e) { // Logger.e(e.toString()); } finally { if(input != null) { try { input.close(); } catch(IOException e) { // Logger.e(e.toString()); } } } return null; } /** * generate a blurred bitmap from given one * * referenced: http://incubator.quasimondo.com/processing/superfastblur.pde * * @param original * @param radius * @return */ public Bitmap getBlurredBitmap(Bitmap original, int radius) { if (radius < 1) return null; int width = original.getWidth(); int height = original.getHeight(); int wm = width - 1; int hm = height - 1; int wh = width * height; int div = radius + radius + 1; int r[] = new int[wh]; int g[] = new int[wh]; int b[] = new int[wh]; int rsum, gsum, bsum, x, y, i, p, p1, p2, yp, yi, yw; int vmin[] = new int[Math.max(width, height)]; int vmax[] = new int[Math.max(width,height)]; int dv[] = new int[256 * div]; for (i=0; i<256*div; i++) dv[i] = i / div; int[] blurredBitmap = new int[wh]; original.getPixels(blurredBitmap, 0, width, 0, 0, width, height); yw = 0; yi = 0; for (y=0; y<height; y++) { rsum = 0; gsum = 0; bsum = 0; for(i=-radius; i<=radius; i++) { p = blurredBitmap[yi + Math.min(wm, Math.max(i,0))]; rsum += (p & 0xff0000) >> 16; gsum += (p & 0x00ff00) >> 8; bsum += p & 0x0000ff; } for (x=0; x<width; x++) { r[yi] = dv[rsum]; g[yi] = dv[gsum]; b[yi] = dv[bsum]; if(y==0) { vmin[x] = Math.min(x + radius+1,wm); vmax[x] = Math.max(x - radius,0); } p1 = blurredBitmap[yw + vmin[x]]; p2 = blurredBitmap[yw + vmax[x]]; rsum += ((p1 & 0xff0000)-(p2 & 0xff0000))>>16; gsum += ((p1 & 0x00ff00)-(p2 & 0x00ff00))>>8; bsum += (p1 & 0x0000ff)-(p2 & 0x0000ff); yi ++; } yw += width; } for (x=0; x<width; x++) { rsum=gsum=bsum=0; yp =- radius * width; for(i=-radius; i<=radius; i++) { yi = Math.max(0,yp) + x; rsum += r[yi]; gsum += g[yi]; bsum += b[yi]; yp += width; } yi = x; for (y=0; y<height; y++) { blurredBitmap[yi] = 0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum]; if(x == 0) { vmin[y] = Math.min(y + radius + 1, hm) * width; vmax[y] = Math.max(y - radius, 0) * width; } p1 = x + vmin[y]; p2 = x + vmax[y]; rsum += r[p1] - r[p2]; gsum += g[p1] - g[p2]; bsum += b[p1] - b[p2]; yi += width; } } return Bitmap.createBitmap(blurredBitmap, width, height, Bitmap.Config.RGB_565); } /** * calculate optimal preview size from given parameters * <br> * referenced: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html * * @param sizes obtained from camera.getParameters().getSupportedPreviewSizes() * @param w * @param h * @return */ public static Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.05; double targetRatio = (double) w / h; if (sizes == null) return null; Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; // Try to find an size match aspect ratio and size for (Size size : sizes) { double ratio = (double) size.width / size.height; if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } // Cannot find the one match the aspect ratio, ignore the requirement if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } return optimalSize; } }
Compress Bitmap
//package org.andlib.helpers.image; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Map; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.hardware.Camera.Size; import android.view.View; final class ImageUtility { public static final int READ_BUFFER_SIZE = 32 * 1024; //32KB /** * * @param path * @param sampleSize 1 = 100%, 2 = 50%(1/2), 4 = 25%(1/4), ... * @return */ public static Bitmap getBitmapFromLocalPath(String path, int sampleSize) { try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = sampleSize; return BitmapFactory.decodeFile(path, options); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param bytes * @return */ public static Bitmap getBitmapFromBytes(byte[] bytes) { try { return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param bitmap * @param quality 1 ~ 100 * @return */ public static byte[] compressBitmap(Bitmap bitmap, int quality) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, quality, baos); return baos.toByteArray(); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param srcBitmap * @param newWidth * @param newHeight * @return */ public static Bitmap getResizedBitmap(Bitmap srcBitmap, int newWidth, int newHeight) { try { return Bitmap.createScaledBitmap(srcBitmap, newWidth, newHeight, true); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * captures given view and converts it to a bitmap * @param view * @return */ public static Bitmap captureViewToBitmap(View view) { Bitmap result = null; try { result = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.RGB_565); view.draw(new Canvas(result)); } catch(Exception e) { //Logger.e(e.toString()); } return result; } /** * * @param original * @param format * @param quality * @param outputLocation * @return */ public static boolean saveBitmap(Bitmap original, Bitmap.CompressFormat format, int quality, String outputLocation) { if(original == null) return false; try { return original.compress(format, quality, new FileOutputStream(outputLocation)); } catch(Exception e) { // Logger.e(e.toString()); } return false; } /** * * @param filepath * @param widthLimit * @param heightLimit * @param totalSize * @return */ public static Bitmap getResizedBitmap(String filepath, int widthLimit, int heightLimit, int totalSize) { int outWidth = 0; int outHeight = 0; int resize = 1; InputStream input = null; try { input = new FileInputStream(new File(filepath)); BitmapFactory.Options getSizeOpt = new BitmapFactory.Options(); getSizeOpt.inJustDecodeBounds = true; BitmapFactory.decodeStream(input, null, getSizeOpt); outWidth = getSizeOpt.outWidth; outHeight = getSizeOpt.outHeight; while((outWidth / resize) > widthLimit || (outHeight / resize) > heightLimit) { resize *= 2; } resize = resize * (totalSize + 15) / 15; BitmapFactory.Options resizeOpt = new BitmapFactory.Options(); resizeOpt.inSampleSize = resize; input.close(); input = null; input = new FileInputStream(new File(filepath)); Bitmap bitmapImage = BitmapFactory.decodeStream(input, null, resizeOpt); return bitmapImage; } catch(Exception e) { // Logger.e(e.toString()); } finally { if(input != null) { try { input.close(); } catch(IOException e) { // Logger.e(e.toString()); } } } return null; } /** * generate a blurred bitmap from given one * * referenced: http://incubator.quasimondo.com/processing/superfastblur.pde * * @param original * @param radius * @return */ public Bitmap getBlurredBitmap(Bitmap original, int radius) { if (radius < 1) return null; int width = original.getWidth(); int height = original.getHeight(); int wm = width - 1; int hm = height - 1; int wh = width * height; int div = radius + radius + 1; int r[] = new int[wh]; int g[] = new int[wh]; int b[] = new int[wh]; int rsum, gsum, bsum, x, y, i, p, p1, p2, yp, yi, yw; int vmin[] = new int[Math.max(width, height)]; int vmax[] = new int[Math.max(width,height)]; int dv[] = new int[256 * div]; for (i=0; i<256*div; i++) dv[i] = i / div; int[] blurredBitmap = new int[wh]; original.getPixels(blurredBitmap, 0, width, 0, 0, width, height); yw = 0; yi = 0; for (y=0; y<height; y++) { rsum = 0; gsum = 0; bsum = 0; for(i=-radius; i<=radius; i++) { p = blurredBitmap[yi + Math.min(wm, Math.max(i,0))]; rsum += (p & 0xff0000) >> 16; gsum += (p & 0x00ff00) >> 8; bsum += p & 0x0000ff; } for (x=0; x<width; x++) { r[yi] = dv[rsum]; g[yi] = dv[gsum]; b[yi] = dv[bsum]; if(y==0) { vmin[x] = Math.min(x + radius+1,wm); vmax[x] = Math.max(x - radius,0); } p1 = blurredBitmap[yw + vmin[x]]; p2 = blurredBitmap[yw + vmax[x]]; rsum += ((p1 & 0xff0000)-(p2 & 0xff0000))>>16; gsum += ((p1 & 0x00ff00)-(p2 & 0x00ff00))>>8; bsum += (p1 & 0x0000ff)-(p2 & 0x0000ff); yi ++; } yw += width; } for (x=0; x<width; x++) { rsum=gsum=bsum=0; yp =- radius * width; for(i=-radius; i<=radius; i++) { yi = Math.max(0,yp) + x; rsum += r[yi]; gsum += g[yi]; bsum += b[yi]; yp += width; } yi = x; for (y=0; y<height; y++) { blurredBitmap[yi] = 0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum]; if(x == 0) { vmin[y] = Math.min(y + radius + 1, hm) * width; vmax[y] = Math.max(y - radius, 0) * width; } p1 = x + vmin[y]; p2 = x + vmax[y]; rsum += r[p1] - r[p2]; gsum += g[p1] - g[p2]; bsum += b[p1] - b[p2]; yi += width; } } return Bitmap.createBitmap(blurredBitmap, width, height, Bitmap.Config.RGB_565); } /** * calculate optimal preview size from given parameters * <br> * referenced: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html * * @param sizes obtained from camera.getParameters().getSupportedPreviewSizes() * @param w * @param h * @return */ public static Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.05; double targetRatio = (double) w / h; if (sizes == null) return null; Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; // Try to find an size match aspect ratio and size for (Size size : sizes) { double ratio = (double) size.width / size.height; if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } // Cannot find the one match the aspect ratio, ignore the requirement if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } return optimalSize; } }
//package org.andlib.helpers.image; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Map; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.hardware.Camera.Size; import android.view.View; */ final class ImageUtility { public static final int READ_BUFFER_SIZE = 32 * 1024; //32KB /** * * @param path * @param sampleSize 1 = 100%, 2 = 50%(1/2), 4 = 25%(1/4), ... * @return */ public static Bitmap getBitmapFromLocalPath(String path, int sampleSize) { try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = sampleSize; return BitmapFactory.decodeFile(path, options); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param bytes * @return */ public static Bitmap getBitmapFromBytes(byte[] bytes) { try { return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param bitmap * @param quality 1 ~ 100 * @return */ public static byte[] compressBitmap(Bitmap bitmap, int quality) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, quality, baos); return baos.toByteArray(); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param srcBitmap * @param newWidth * @param newHeight * @return */ public static Bitmap getResizedBitmap(Bitmap srcBitmap, int newWidth, int newHeight) { try { return Bitmap.createScaledBitmap(srcBitmap, newWidth, newHeight, true); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * captures given view and converts it to a bitmap * @param view * @return */ public static Bitmap captureViewToBitmap(View view) { Bitmap result = null; try { result = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.RGB_565); view.draw(new Canvas(result)); } catch(Exception e) { //Logger.e(e.toString()); } return result; } /** * * @param original * @param format * @param quality * @param outputLocation * @return */ public static boolean saveBitmap(Bitmap original, Bitmap.CompressFormat format, int quality, String outputLocation) { if(original == null) return false; try { return original.compress(format, quality, new FileOutputStream(outputLocation)); } catch(Exception e) { // Logger.e(e.toString()); } return false; } /** * * @param filepath * @param widthLimit * @param heightLimit * @param totalSize * @return */ public static Bitmap getResizedBitmap(String filepath, int widthLimit, int heightLimit, int totalSize) { int outWidth = 0; int outHeight = 0; int resize = 1; InputStream input = null; try { input = new FileInputStream(new File(filepath)); BitmapFactory.Options getSizeOpt = new BitmapFactory.Options(); getSizeOpt.inJustDecodeBounds = true; BitmapFactory.decodeStream(input, null, getSizeOpt); outWidth = getSizeOpt.outWidth; outHeight = getSizeOpt.outHeight; while((outWidth / resize) > widthLimit || (outHeight / resize) > heightLimit) { resize *= 2; } resize = resize * (totalSize + 15) / 15; BitmapFactory.Options resizeOpt = new BitmapFactory.Options(); resizeOpt.inSampleSize = resize; input.close(); input = null; input = new FileInputStream(new File(filepath)); Bitmap bitmapImage = BitmapFactory.decodeStream(input, null, resizeOpt); return bitmapImage; } catch(Exception e) { // Logger.e(e.toString()); } finally { if(input != null) { try { input.close(); } catch(IOException e) { // Logger.e(e.toString()); } } } return null; } public Bitmap getBlurredBitmap(Bitmap original, int radius) { if (radius < 1) return null; int width = original.getWidth(); int height = original.getHeight(); int wm = width - 1; int hm = height - 1; int wh = width * height; int div = radius + radius + 1; int r[] = new int[wh]; int g[] = new int[wh]; int b[] = new int[wh]; int rsum, gsum, bsum, x, y, i, p, p1, p2, yp, yi, yw; int vmin[] = new int[Math.max(width, height)]; int vmax[] = new int[Math.max(width,height)]; int dv[] = new int[256 * div]; for (i=0; i<256*div; i++) dv[i] = i / div; int[] blurredBitmap = new int[wh]; original.getPixels(blurredBitmap, 0, width, 0, 0, width, height); yw = 0; yi = 0; for (y=0; y<height; y++) { rsum = 0; gsum = 0; bsum = 0; for(i=-radius; i<=radius; i++) { p = blurredBitmap[yi + Math.min(wm, Math.max(i,0))]; rsum += (p & 0xff0000) >> 16; gsum += (p & 0x00ff00) >> 8; bsum += p & 0x0000ff; } for (x=0; x<width; x++) { r[yi] = dv[rsum]; g[yi] = dv[gsum]; b[yi] = dv[bsum]; if(y==0) { vmin[x] = Math.min(x + radius+1,wm); vmax[x] = Math.max(x - radius,0); } p1 = blurredBitmap[yw + vmin[x]]; p2 = blurredBitmap[yw + vmax[x]]; rsum += ((p1 & 0xff0000)-(p2 & 0xff0000))>>16; gsum += ((p1 & 0x00ff00)-(p2 & 0x00ff00))>>8; bsum += (p1 & 0x0000ff)-(p2 & 0x0000ff); yi ++; } yw += width; } for (x=0; x<width; x++) { rsum=gsum=bsum=0; yp =- radius * width; for(i=-radius; i<=radius; i++) { yi = Math.max(0,yp) + x; rsum += r[yi]; gsum += g[yi]; bsum += b[yi]; yp += width; } yi = x; for (y=0; y<height; y++) { blurredBitmap[yi] = 0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum]; if(x == 0) { vmin[y] = Math.min(y + radius + 1, hm) * width; vmax[y] = Math.max(y - radius, 0) * width; } p1 = x + vmin[y]; p2 = x + vmax[y]; rsum += r[p1] - r[p2]; gsum += g[p1] - g[p2]; bsum += b[p1] - b[p2]; yi += width; } } return Bitmap.createBitmap(blurredBitmap, width, height, Bitmap.Config.RGB_565); } /** * calculate optimal preview size from given parameters * <br> * referenced: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html * * @param sizes obtained from camera.getParameters().getSupportedPreviewSizes() * @param w * @param h * @return */ public static Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.05; double targetRatio = (double) w / h; if (sizes == null) return null; Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; // Try to find an size match aspect ratio and size for (Size size : sizes) { double ratio = (double) size.width / size.height; if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } // Cannot find the one match the aspect ratio, ignore the requirement if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } return optimalSize; } }
captures given view and converts it to a bitmap
//package org.andlib.helpers.image; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Map; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.hardware.Camera.Size; import android.view.View; final class ImageUtility { public static final int READ_BUFFER_SIZE = 32 * 1024; //32KB /** * * @param path * @param sampleSize 1 = 100%, 2 = 50%(1/2), 4 = 25%(1/4), ... * @return */ public static Bitmap getBitmapFromLocalPath(String path, int sampleSize) { try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = sampleSize; return BitmapFactory.decodeFile(path, options); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param bytes * @return */ public static Bitmap getBitmapFromBytes(byte[] bytes) { try { return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param bitmap * @param quality 1 ~ 100 * @return */ public static byte[] compressBitmap(Bitmap bitmap, int quality) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, quality, baos); return baos.toByteArray(); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param srcBitmap * @param newWidth * @param newHeight * @return */ public static Bitmap getResizedBitmap(Bitmap srcBitmap, int newWidth, int newHeight) { try { return Bitmap.createScaledBitmap(srcBitmap, newWidth, newHeight, true); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * captures given view and converts it to a bitmap * @param view * @return */ public static Bitmap captureViewToBitmap(View view) { Bitmap result = null; try { result = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.RGB_565); view.draw(new Canvas(result)); } catch(Exception e) { //Logger.e(e.toString()); } return result; } /** * * @param original * @param format * @param quality * @param outputLocation * @return */ public static boolean saveBitmap(Bitmap original, Bitmap.CompressFormat format, int quality, String outputLocation) { if(original == null) return false; try { return original.compress(format, quality, new FileOutputStream(outputLocation)); } catch(Exception e) { // Logger.e(e.toString()); } return false; } /** * * @param filepath * @param widthLimit * @param heightLimit * @param totalSize * @return */ public static Bitmap getResizedBitmap(String filepath, int widthLimit, int heightLimit, int totalSize) { int outWidth = 0; int outHeight = 0; int resize = 1; InputStream input = null; try { input = new FileInputStream(new File(filepath)); BitmapFactory.Options getSizeOpt = new BitmapFactory.Options(); getSizeOpt.inJustDecodeBounds = true; BitmapFactory.decodeStream(input, null, getSizeOpt); outWidth = getSizeOpt.outWidth; outHeight = getSizeOpt.outHeight; while((outWidth / resize) > widthLimit || (outHeight / resize) > heightLimit) { resize *= 2; } resize = resize * (totalSize + 15) / 15; BitmapFactory.Options resizeOpt = new BitmapFactory.Options(); resizeOpt.inSampleSize = resize; input.close(); input = null; input = new FileInputStream(new File(filepath)); Bitmap bitmapImage = BitmapFactory.decodeStream(input, null, resizeOpt); return bitmapImage; } catch(Exception e) { // Logger.e(e.toString()); } finally { if(input != null) { try { input.close(); } catch(IOException e) { // Logger.e(e.toString()); } } } return null; } /** * generate a blurred bitmap from given one * * referenced: http://incubator.quasimondo.com/processing/superfastblur.pde * * @param original * @param radius * @return */ public Bitmap getBlurredBitmap(Bitmap original, int radius) { if (radius < 1) return null; int width = original.getWidth(); int height = original.getHeight(); int wm = width - 1; int hm = height - 1; int wh = width * height; int div = radius + radius + 1; int r[] = new int[wh]; int g[] = new int[wh]; int b[] = new int[wh]; int rsum, gsum, bsum, x, y, i, p, p1, p2, yp, yi, yw; int vmin[] = new int[Math.max(width, height)]; int vmax[] = new int[Math.max(width,height)]; int dv[] = new int[256 * div]; for (i=0; i<256*div; i++) dv[i] = i / div; int[] blurredBitmap = new int[wh]; original.getPixels(blurredBitmap, 0, width, 0, 0, width, height); yw = 0; yi = 0; for (y=0; y<height; y++) { rsum = 0; gsum = 0; bsum = 0; for(i=-radius; i<=radius; i++) { p = blurredBitmap[yi + Math.min(wm, Math.max(i,0))]; rsum += (p & 0xff0000) >> 16; gsum += (p & 0x00ff00) >> 8; bsum += p & 0x0000ff; } for (x=0; x<width; x++) { r[yi] = dv[rsum]; g[yi] = dv[gsum]; b[yi] = dv[bsum]; if(y==0) { vmin[x] = Math.min(x + radius+1,wm); vmax[x] = Math.max(x - radius,0); } p1 = blurredBitmap[yw + vmin[x]]; p2 = blurredBitmap[yw + vmax[x]]; rsum += ((p1 & 0xff0000)-(p2 & 0xff0000))>>16; gsum += ((p1 & 0x00ff00)-(p2 & 0x00ff00))>>8; bsum += (p1 & 0x0000ff)-(p2 & 0x0000ff); yi ++; } yw += width; } for (x=0; x<width; x++) { rsum=gsum=bsum=0; yp =- radius * width; for(i=-radius; i<=radius; i++) { yi = Math.max(0,yp) + x; rsum += r[yi]; gsum += g[yi]; bsum += b[yi]; yp += width; } yi = x; for (y=0; y<height; y++) { blurredBitmap[yi] = 0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum]; if(x == 0) { vmin[y] = Math.min(y + radius + 1, hm) * width; vmax[y] = Math.max(y - radius, 0) * width; } p1 = x + vmin[y]; p2 = x + vmax[y]; rsum += r[p1] - r[p2]; gsum += g[p1] - g[p2]; bsum += b[p1] - b[p2]; yi += width; } } return Bitmap.createBitmap(blurredBitmap, width, height, Bitmap.Config.RGB_565); } /** * calculate optimal preview size from given parameters * <br> * referenced: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html * * @param sizes obtained from camera.getParameters().getSupportedPreviewSizes() * @param w * @param h * @return */ public static Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.05; double targetRatio = (double) w / h; if (sizes == null) return null; Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; // Try to find an size match aspect ratio and size for (Size size : sizes) { double ratio = (double) size.width / size.height; if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } // Cannot find the one match the aspect ratio, ignore the requirement if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } return optimalSize; } }
//package org.andlib.helpers.image; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Map; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.hardware.Camera.Size; import android.view.View; final class ImageUtility { public static final int READ_BUFFER_SIZE = 32 * 1024; //32KB /** * * @param path * @param sampleSize 1 = 100%, 2 = 50%(1/2), 4 = 25%(1/4), ... * @return */ public static Bitmap getBitmapFromLocalPath(String path, int sampleSize) { try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = sampleSize; return BitmapFactory.decodeFile(path, options); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param bytes * @return */ public static Bitmap getBitmapFromBytes(byte[] bytes) { try { return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param bitmap * @param quality 1 ~ 100 * @return */ public static byte[] compressBitmap(Bitmap bitmap, int quality) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, quality, baos); return baos.toByteArray(); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param srcBitmap * @param newWidth * @param newHeight * @return */ public static Bitmap getResizedBitmap(Bitmap srcBitmap, int newWidth, int newHeight) { try { return Bitmap.createScaledBitmap(srcBitmap, newWidth, newHeight, true); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * captures given view and converts it to a bitmap * @param view * @return */ public static Bitmap captureViewToBitmap(View view) { Bitmap result = null; try { result = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.RGB_565); view.draw(new Canvas(result)); } catch(Exception e) { //Logger.e(e.toString()); } return result; } /** * * @param original * @param format * @param quality * @param outputLocation * @return */ public static boolean saveBitmap(Bitmap original, Bitmap.CompressFormat format, int quality, String outputLocation) { if(original == null) return false; try { return original.compress(format, quality, new FileOutputStream(outputLocation)); } catch(Exception e) { // Logger.e(e.toString()); } return false; } /** * * @param filepath * @param widthLimit * @param heightLimit * @param totalSize * @return */ public static Bitmap getResizedBitmap(String filepath, int widthLimit, int heightLimit, int totalSize) { int outWidth = 0; int outHeight = 0; int resize = 1; InputStream input = null; try { input = new FileInputStream(new File(filepath)); BitmapFactory.Options getSizeOpt = new BitmapFactory.Options(); getSizeOpt.inJustDecodeBounds = true; BitmapFactory.decodeStream(input, null, getSizeOpt); outWidth = getSizeOpt.outWidth; outHeight = getSizeOpt.outHeight; while((outWidth / resize) > widthLimit || (outHeight / resize) > heightLimit) { resize *= 2; } resize = resize * (totalSize + 15) / 15; BitmapFactory.Options resizeOpt = new BitmapFactory.Options(); resizeOpt.inSampleSize = resize; input.close(); input = null; input = new FileInputStream(new File(filepath)); Bitmap bitmapImage = BitmapFactory.decodeStream(input, null, resizeOpt); return bitmapImage; } catch(Exception e) { // Logger.e(e.toString()); } finally { if(input != null) { try { input.close(); } catch(IOException e) { // Logger.e(e.toString()); } } } return null; } /** * generate a blurred bitmap from given one * * referenced: http://incubator.quasimondo.com/processing/superfastblur.pde * * @param original * @param radius * @return */ public Bitmap getBlurredBitmap(Bitmap original, int radius) { if (radius < 1) return null; int width = original.getWidth(); int height = original.getHeight(); int wm = width - 1; int hm = height - 1; int wh = width * height; int div = radius + radius + 1; int r[] = new int[wh]; int g[] = new int[wh]; int b[] = new int[wh]; int rsum, gsum, bsum, x, y, i, p, p1, p2, yp, yi, yw; int vmin[] = new int[Math.max(width, height)]; int vmax[] = new int[Math.max(width,height)]; int dv[] = new int[256 * div]; for (i=0; i<256*div; i++) dv[i] = i / div; int[] blurredBitmap = new int[wh]; original.getPixels(blurredBitmap, 0, width, 0, 0, width, height); yw = 0; yi = 0; for (y=0; y<height; y++) { rsum = 0; gsum = 0; bsum = 0; for(i=-radius; i<=radius; i++) { p = blurredBitmap[yi + Math.min(wm, Math.max(i,0))]; rsum += (p & 0xff0000) >> 16; gsum += (p & 0x00ff00) >> 8; bsum += p & 0x0000ff; } for (x=0; x<width; x++) { r[yi] = dv[rsum]; g[yi] = dv[gsum]; b[yi] = dv[bsum]; if(y==0) { vmin[x] = Math.min(x + radius+1,wm); vmax[x] = Math.max(x - radius,0); } p1 = blurredBitmap[yw + vmin[x]]; p2 = blurredBitmap[yw + vmax[x]]; rsum += ((p1 & 0xff0000)-(p2 & 0xff0000))>>16; gsum += ((p1 & 0x00ff00)-(p2 & 0x00ff00))>>8; bsum += (p1 & 0x0000ff)-(p2 & 0x0000ff); yi ++; } yw += width; } for (x=0; x<width; x++) { rsum=gsum=bsum=0; yp =- radius * width; for(i=-radius; i<=radius; i++) { yi = Math.max(0,yp) + x; rsum += r[yi]; gsum += g[yi]; bsum += b[yi]; yp += width; } yi = x; for (y=0; y<height; y++) { blurredBitmap[yi] = 0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum]; if(x == 0) { vmin[y] = Math.min(y + radius + 1, hm) * width; vmax[y] = Math.max(y - radius, 0) * width; } p1 = x + vmin[y]; p2 = x + vmax[y]; rsum += r[p1] - r[p2]; gsum += g[p1] - g[p2]; bsum += b[p1] - b[p2]; yi += width; } } return Bitmap.createBitmap(blurredBitmap, width, height, Bitmap.Config.RGB_565); } /** * calculate optimal preview size from given parameters * <br> * referenced: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html * * @param sizes obtained from camera.getParameters().getSupportedPreviewSizes() * @param w * @param h * @return */ public static Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.05; double targetRatio = (double) w / h; if (sizes == null) return null; Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; // Try to find an size match aspect ratio and size for (Size size : sizes) { double ratio = (double) size.width / size.height; if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } // Cannot find the one match the aspect ratio, ignore the requirement if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } return optimalSize; } }
//package org.andlib.helpers.image; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Map; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.hardware.Camera.Size; import android.view.View; final class ImageUtility { public static final int READ_BUFFER_SIZE = 32 * 1024; //32KB /** * * @param path * @param sampleSize 1 = 100%, 2 = 50%(1/2), 4 = 25%(1/4), ... * @return */ public static Bitmap getBitmapFromLocalPath(String path, int sampleSize) { try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = sampleSize; return BitmapFactory.decodeFile(path, options); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param bytes * @return */ public static Bitmap getBitmapFromBytes(byte[] bytes) { try { return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param bitmap * @param quality 1 ~ 100 * @return */ public static byte[] compressBitmap(Bitmap bitmap, int quality) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, quality, baos); return baos.toByteArray(); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param srcBitmap * @param newWidth * @param newHeight * @return */ public static Bitmap getResizedBitmap(Bitmap srcBitmap, int newWidth, int newHeight) { try { return Bitmap.createScaledBitmap(srcBitmap, newWidth, newHeight, true); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * captures given view and converts it to a bitmap * @param view * @return */ public static Bitmap captureViewToBitmap(View view) { Bitmap result = null; try { result = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.RGB_565); view.draw(new Canvas(result)); } catch(Exception e) { //Logger.e(e.toString()); } return result; } /** * * @param original * @param format * @param quality * @param outputLocation * @return */ public static boolean saveBitmap(Bitmap original, Bitmap.CompressFormat format, int quality, String outputLocation) { if(original == null) return false; try { return original.compress(format, quality, new FileOutputStream(outputLocation)); } catch(Exception e) { // Logger.e(e.toString()); } return false; } /** * * @param filepath * @param widthLimit * @param heightLimit * @param totalSize * @return */ public static Bitmap getResizedBitmap(String filepath, int widthLimit, int heightLimit, int totalSize) { int outWidth = 0; int outHeight = 0; int resize = 1; InputStream input = null; try { input = new FileInputStream(new File(filepath)); BitmapFactory.Options getSizeOpt = new BitmapFactory.Options(); getSizeOpt.inJustDecodeBounds = true; BitmapFactory.decodeStream(input, null, getSizeOpt); outWidth = getSizeOpt.outWidth; outHeight = getSizeOpt.outHeight; while((outWidth / resize) > widthLimit || (outHeight / resize) > heightLimit) { resize *= 2; } resize = resize * (totalSize + 15) / 15; BitmapFactory.Options resizeOpt = new BitmapFactory.Options(); resizeOpt.inSampleSize = resize; input.close(); input = null; input = new FileInputStream(new File(filepath)); Bitmap bitmapImage = BitmapFactory.decodeStream(input, null, resizeOpt); return bitmapImage; } catch(Exception e) { // Logger.e(e.toString()); } finally { if(input != null) { try { input.close(); } catch(IOException e) { // Logger.e(e.toString()); } } } return null; } /** * generate a blurred bitmap from given one * * referenced: http://incubator.quasimondo.com/processing/superfastblur.pde * * @param original * @param radius * @return */ public Bitmap getBlurredBitmap(Bitmap original, int radius) { if (radius < 1) return null; int width = original.getWidth(); int height = original.getHeight(); int wm = width - 1; int hm = height - 1; int wh = width * height; int div = radius + radius + 1; int r[] = new int[wh]; int g[] = new int[wh]; int b[] = new int[wh]; int rsum, gsum, bsum, x, y, i, p, p1, p2, yp, yi, yw; int vmin[] = new int[Math.max(width, height)]; int vmax[] = new int[Math.max(width,height)]; int dv[] = new int[256 * div]; for (i=0; i<256*div; i++) dv[i] = i / div; int[] blurredBitmap = new int[wh]; original.getPixels(blurredBitmap, 0, width, 0, 0, width, height); yw = 0; yi = 0; for (y=0; y<height; y++) { rsum = 0; gsum = 0; bsum = 0; for(i=-radius; i<=radius; i++) { p = blurredBitmap[yi + Math.min(wm, Math.max(i,0))]; rsum += (p & 0xff0000) >> 16; gsum += (p & 0x00ff00) >> 8; bsum += p & 0x0000ff; } for (x=0; x<width; x++) { r[yi] = dv[rsum]; g[yi] = dv[gsum]; b[yi] = dv[bsum]; if(y==0) { vmin[x] = Math.min(x + radius+1,wm); vmax[x] = Math.max(x - radius,0); } p1 = blurredBitmap[yw + vmin[x]]; p2 = blurredBitmap[yw + vmax[x]]; rsum += ((p1 & 0xff0000)-(p2 & 0xff0000))>>16; gsum += ((p1 & 0x00ff00)-(p2 & 0x00ff00))>>8; bsum += (p1 & 0x0000ff)-(p2 & 0x0000ff); yi ++; } yw += width; } for (x=0; x<width; x++) { rsum=gsum=bsum=0; yp =- radius * width; for(i=-radius; i<=radius; i++) { yi = Math.max(0,yp) + x; rsum += r[yi]; gsum += g[yi]; bsum += b[yi]; yp += width; } yi = x; for (y=0; y<height; y++) { blurredBitmap[yi] = 0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum]; if(x == 0) { vmin[y] = Math.min(y + radius + 1, hm) * width; vmax[y] = Math.max(y - radius, 0) * width; } p1 = x + vmin[y]; p2 = x + vmax[y]; rsum += r[p1] - r[p2]; gsum += g[p1] - g[p2]; bsum += b[p1] - b[p2]; yi += width; } } return Bitmap.createBitmap(blurredBitmap, width, height, Bitmap.Config.RGB_565); } /** * calculate optimal preview size from given parameters * <br> * referenced: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html * * @param sizes obtained from camera.getParameters().getSupportedPreviewSizes() * @param w * @param h * @return */ public static Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.05; double targetRatio = (double) w / h; if (sizes == null) return null; Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; // Try to find an size match aspect ratio and size for (Size size : sizes) { double ratio = (double) size.width / size.height; if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } // Cannot find the one match the aspect ratio, ignore the requirement if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } return optimalSize; } }
Get Bitmap From Name
//package edu.dhbw.andobjviewer.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; abstract class BaseFileUtil { protected String baseFolder = null; /* (non-Javadoc) * @see edu.dhbw.andobjviewer.util.FileUtilInterface#getBaseFolder() */ public String getBaseFolder() { return baseFolder; } /* (non-Javadoc) * @see edu.dhbw.andobjviewer.util.FileUtilInterface#setBaseFolder(java.io.File) */ public void setBaseFolder(String baseFolder) { this.baseFolder = baseFolder; } /** * get an reader through it's filename * @param name * @return may be null, in case of an exception */ public abstract BufferedReader getReaderFromName(String name); /** * get a bitmap object through an filename. * @param name * @return may be null, in case of an exception */ public abstract Bitmap getBitmapFromName(String name); } public class AssetsFileUtil extends BaseFileUtil { private AssetManager am; public AssetsFileUtil(AssetManager am) { this.am = am; } @Override public Bitmap getBitmapFromName(String name) { InputStream is = getInputStreamFromName(name); return (is==null)?null:BitmapFactory.decodeStream(is); } @Override public BufferedReader getReaderFromName(String name) { InputStream is = getInputStreamFromName(name); return (is==null)?null:new BufferedReader(new InputStreamReader(is)); } private InputStream getInputStreamFromName(String name) { InputStream is; if(baseFolder != null) { try { is = am.open(baseFolder+name); } catch (IOException e) { e.printStackTrace(); return null; } } else { try { is = am.open(name); } catch (IOException e) { e.printStackTrace(); return null; } } return is; } }
Load Bitmap with Context
import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.nio.ShortBuffer; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; class OpenGLUtils { public static Bitmap loadBitmap(Context mContext, int id) { InputStream is = mContext.getResources().openRawResource(id); Bitmap bitmap = null; try { bitmap = BitmapFactory.decodeStream(is); } finally { try { is.close(); } catch (IOException e) { // Ignore. } } return bitmap; } }
Load Bitmap from InputStream
import java.io.InputStream; import java.net.URL; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; class BitmapImageUtil { public static Bitmap loadFrom(String url, Context context, int defaultDrawable) { try { InputStream is = (InputStream) new URL(url).getContent(); try { return BitmapFactory.decodeStream(is); } finally { is.close(); } } catch (Exception e) { return BitmapFactory.decodeResource(context.getResources(), defaultDrawable); } } }
Get Bitmap from Url with HttpURLConnection
//package com.terry.bobobo; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import android.graphics.Bitmap; import android.graphics.BitmapFactory; class HttpUtils { public static Bitmap getImage(URL url) { HttpURLConnection connection = null; try { connection = (HttpURLConnection) url.openConnection(); connection.connect(); int responseCode = connection.getResponseCode(); if (responseCode == 200) { return BitmapFactory.decodeStream(connection.getInputStream()); } else return null; } catch (Exception e) { return null; } finally { if (connection != null) { connection.disconnect(); } } } public static Bitmap getImage(String urlString) { try { URL url = new URL(urlString); return getImage(url); } catch (MalformedURLException e) { return null; } } }
//package com.gaara.test.utils; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; class GraphicsUtils { public static void rotateBitmap(Canvas canvas,Bitmap bitmap,float angle,int alpha,float scale) { /* Matrix matrix = new Matrix(); matrix.setScale(4, 4); Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),matrix, true); matrix = new Matrix(); matrix.setTranslate(resizeBmp.getWidth()/2,resizeBmp.getHeight()/2); matrix.preRotate(angle); matrix.preTranslate(-resizeBmp.getWidth()/2,-resizeBmp.getHeight()/2); matrix.postTranslate((canvas.getWidth()-resizeBmp.getWidth())/2,(canvas.getHeight()-resizeBmp.getHeight())/2); Paint vPaint = new Paint(); vPaint.setStyle( Paint.Style.STROKE ); //??? vPaint.setAlpha(alpha); // Bitmap?????0 ~ 100) canvas.drawBitmap(resizeBmp,matrix,vPaint);*/ Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth()/2, bitmap.getHeight()/2); canvas.drawBitmap(resizeBmp, 0,0,null); } }
Get Texture From Bitmap Resource and BitmapFactory.decodeStream
//package com.galactogolf.utils; import java.io.IOException; import java.io.InputStream; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; /** * Some helper methods * */ public class Util { public static Bitmap getTextureFromBitmapResource(Context context, int resourceId) { InputStream is = context.getResources().openRawResource(resourceId); Bitmap bitmap = null; try { bitmap = BitmapFactory.decodeStream(is); } finally { // Always clear and close try { is.close(); is = null; } catch (IOException e) { } } return bitmap; } }
Drawable to Bitmap
import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.drawable.Drawable; class Main { public static Bitmap Drawable2Bitmap(Drawable drawable) { int width = drawable.getIntrinsicWidth(); int height = drawable.getIntrinsicHeight(); Bitmap bmp = Bitmap .createBitmap(width, height, Bitmap.Config.ARGB_8888); drawable.mutate().setBounds(0, 0, width, height); Canvas c = new Canvas(bmp); drawable.draw(c); return bmp; } }
Save Bitmap to and load from External Storage
//package jp.android.fukuoka.tegaky; import java.io.File; import java.io.FileOutputStream; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Bitmap.CompressFormat; import android.os.Environment; class PictUtil { public static File getSavePath() { File path; if (hasSDCard()) { // SD card path = new File(getSDCardPath() + "/Tegaky/"); path.mkdir(); } else { path = Environment.getDataDirectory(); } return path; } public static String getCacheFilename() { File f = getSavePath(); return f.getAbsolutePath() + "/cache.png"; } public static Bitmap loadFromFile(String filename) { try { File f = new File(filename); if (!f.exists()) { return null; } Bitmap tmp = BitmapFactory.decodeFile(filename); return tmp; } catch (Exception e) { return null; } } public static Bitmap loadFromCacheFile() { return loadFromFile(getCacheFilename()); } public static void saveToCacheFile(Bitmap bmp) { saveToFile(getCacheFilename(),bmp); } public static void saveToFile(String filename,Bitmap bmp) { try { FileOutputStream out = new FileOutputStream(filename); bmp.compress(CompressFormat.PNG, 100, out); out.flush(); out.close(); } catch(Exception e) {} } public static boolean hasSDCard() { // SD???????? String status = Environment.getExternalStorageState(); return status.equals(Environment.MEDIA_MOUNTED); } public static String getSDCardPath() { File path = Environment.getExternalStorageDirectory(); return path.getAbsolutePath(); } }
Get Image Bitmap From Url
import java.io.BufferedInputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.Random; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; class Utils { public static Bitmap getImageBitmapFromUrl(URL url) { Bitmap bm = null; try { HttpURLConnection conn = (HttpURLConnection)url.openConnection(); if(conn.getResponseCode() != 200) { return bm; } conn.connect(); InputStream is = conn.getInputStream(); BufferedInputStream bis = new BufferedInputStream(is); try { bm = BitmapFactory.decodeStream(bis); } catch(OutOfMemoryError ex) { bm = null; } bis.close(); is.close(); } catch (Exception e) {} return bm; } }
Scale Bitmap
import android.graphics.Bitmap; import android.graphics.Matrix; class Utils { public static Bitmap scaleBitmap(Bitmap original, int width, int height) { float scaleWidth = ((float) width) / original.getWidth(); float scaleHeight = ((float) height) / original.getHeight(); Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); return Bitmap.createBitmap(original, 0, 0, original.getWidth(), original.getHeight(), matrix, true); } }
//package com.seleuco.xpectrum.util; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapFactory.Options; import android.os.Build; public abstract class UnscaledBitmapLoader { public static final UnscaledBitmapLoader instance; public static boolean canScale = true; static { canScale = (Integer.parseInt(Build.VERSION.SDK) >= 4); instance = Integer.parseInt(Build.VERSION.SDK) < 4 ? new Old() : new New(); } public static Bitmap loadFromResource(Resources resources, int resId, BitmapFactory.Options options) { return instance.load(resources, resId, options); } public static void setDensity(Bitmap bmp) { instance.setDen(bmp); } private static class Old extends UnscaledBitmapLoader { @Override Bitmap load(Resources resources, int resId, Options options) { return BitmapFactory.decodeResource(resources, resId, options); } void setDen(Bitmap bmp) { } } private static class New extends UnscaledBitmapLoader { @Override Bitmap load(Resources resources, int resId, Options options) { if (options == null) options = new BitmapFactory.Options(); options.inScaled = false; return BitmapFactory.decodeResource(resources, resId, options); } @Override void setDen(Bitmap bmp) { bmp.setDensity(Bitmap.DENSITY_NONE); } } abstract Bitmap load(Resources resources, int resId, BitmapFactory.Options options); abstract void setDen(Bitmap bmp); }
Save Bitmap to External Storage Directory
// Copyright (C) 2009-2010 Mihai Preda //package calculator; import android.graphics.Bitmap; import android.os.Environment; import android.os.Build; import java.nio.ShortBuffer; import java.io.*; class Util { public static final int SDK_VERSION = getSdkVersion(); private static int getSdkVersion() { try { return Integer.parseInt(Build.VERSION.SDK); } catch (NumberFormatException e) { return 3; } } static String saveBitmap(Bitmap bitmap, String dir, String baseName) { try { File sdcard = Environment.getExternalStorageDirectory(); File pictureDir = new File(sdcard, dir); pictureDir.mkdirs(); File f = null; for (int i = 1; i < 200; ++i) { String name = baseName + i + ".png"; f = new File(pictureDir, name); if (!f.exists()) { break; } } if (!f.exists()) { String name = f.getAbsolutePath(); FileOutputStream fos = new FileOutputStream(name); bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); fos.flush(); fos.close(); return name; } } catch (Exception e) { } finally { /* if (fos != null) { fos.close(); } */ } return null; } static void bitmapBGRtoRGB(Bitmap bitmap, int width, int height) { int size = width * height; short data[] = new short[size]; ShortBuffer buf = ShortBuffer.wrap(data); bitmap.copyPixelsToBuffer(buf); for (int i = 0; i < size; ++i) { //BGR-565 to RGB-565 short v = data[i]; data[i] = (short) (((v&0x1f) << 11) | (v&0x7e0) | ((v&0xf800) >> 11)); } buf.rewind(); bitmap.copyPixelsFromBuffer(buf); } }
Compress and save Bitmap image
//package net.bitquill.ocr; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.util.Log; /** * Simple utility class to dump image data for later debugging. */ class FileDumpUtil { private static final String TAG = "FileDumpUtil"; private static final File sDumpDirectory = new File( "/sdcard/net.bitquill.ocr"); synchronized static public void init() { // Create directory, if necessary if (!sDumpDirectory.exists()) { sDumpDirectory.mkdirs(); } } synchronized static public void dump(String prefix, Bitmap img) { FileOutputStream os = null; try { long timestamp = System.currentTimeMillis(); File dumpFile = new File(sDumpDirectory, prefix + timestamp + ".png"); os = new FileOutputStream(dumpFile); img.compress(CompressFormat.PNG, 100, os); } catch (IOException ioe) { Log.e(TAG, "GrayImage dump failed", ioe); } finally { try { os.close(); } catch (Throwable t) { // Ignore } } } }
//package com.litecoding.classkit.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Log; /** * This class contains utils for Bitmap downloading, processing etc. * * @author Dmitry S. Vorobiev * */ public class BitmapUtils { public static int IO_BUFFER_SIZE = 1024 * 1024; /** * Downloads image and creates a Bitmap object * @param url URL of image to be downloaded * @return downloaded bitmap or null if error occurred */ public static Bitmap loadBitmapFromUrl(String url) { Bitmap bitmap = null; try { bitmap = loadBitmapFromUrl(new URL(url)); } catch(Exception e) { } return bitmap; } /** * Downloads image and creates a Bitmap object * @param url URL of image to be downloaded * @return downloaded bitmap or null if error occurred */ public static Bitmap loadBitmapFromUrl(URL url) { Bitmap bitmap = null; InputStream in = null; BufferedOutputStream out = null; try { in = new BufferedInputStream(url.openStream(), IO_BUFFER_SIZE); final ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE); byte[] buf = new byte[1024]; while(in.available() > 0) { int cntBytes = in.read(buf); out.write(buf, 0, cntBytes); } out.flush(); final byte[] data = dataStream.toByteArray(); BitmapFactory.Options options = new BitmapFactory.Options(); //options.inSampleSize = 1; bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,options); } catch (IOException e) { } finally { try { in.close(); out.close(); } catch(IOException e) { } } return bitmap; } }
Rotate a Bitmap
import android.graphics.Bitmap; import android.graphics.Matrix; class Utility { public static Bitmap rotate(Bitmap b, int degrees) { if (degrees != 0 && b != null) { Matrix m = new Matrix(); m.setRotate(degrees, (float) b.getWidth() / 2, (float) b.getHeight() / 2); Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true); if (b != b2) { b.recycle(); b = b2; } } return b; } }
Save/load Bitmap
//package com.sofurry.favorites.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; import android.os.Environment; import android.util.Log; class SubmissionStorage { public static Bitmap loadSubmissionImage(int id) { return loadIcon("image" + id); } public static void saveSubmissionImage(int id, Bitmap icon) { saveIcon("image" + id, icon); } public static void deleteSubmissionImage(int id) { FileStorage.deleteFile("image" + id); } private static Bitmap loadIcon(String filename) { FileInputStream is; Bitmap bitmap = null; try { is = FileStorage.getFileInputStream(filename); if (is != null && is.available() > 0) { bitmap = BitmapFactory.decodeStream(is); } else { Log.w("soFurryApp", "Can't load from external storage"); } } catch (Exception e) { Log.e("soFurryApp", "error in loadIcon", e); } return bitmap; } private static void saveIcon(String filename, Bitmap icon) { FileOutputStream os; try { os = FileStorage.getFileOutputStream(filename); if (os != null) { icon.compress(CompressFormat.JPEG, 80, os); } else { Log.w("soFurryApp", "Can't save to external storage"); } } catch (Exception e) { Log.e("soFurryApp", "error in saveIcon", e); } } public static String saveImageToGallery(String filename, Bitmap icon) { String fullfilepath = null; try { File path = new File(Environment.getExternalStorageDirectory() + "/FurryWallpapers"); path.mkdirs(); File file = new File(path, filename); fullfilepath = file.getAbsolutePath(); Log.d("SF Wallpaper", "Saving image " + file.getAbsolutePath()); // file.createNewFile(); FileOutputStream os = new FileOutputStream(file); icon.compress(CompressFormat.JPEG, 80, os); os.close(); } catch (Exception e) { Log.w("ExternalStorage", "Error writing file", e); } return fullfilepath; } } class FileStorage { private static Context context; public static FileOutputStream getFileOutputStream(String filename) throws IOException { File f = null; f = new File(context.getCacheDir() + "/" + filename); Log.d("FileStorage", "writing file " + f.getAbsolutePath() + " - " + filename); if (f.createNewFile() && f.canWrite()) { return new FileOutputStream(f); } return null; } public static FileInputStream getFileInputStream(String filename) throws FileNotFoundException { File f = null; f = new File(context.getCacheDir() + "/" + filename); if (f.canRead()) { Log.d("FileStorage", "reading file " + f.getAbsolutePath() + " - " + filename); return new FileInputStream(f); } else { Log.d("FileStorage", "Can't read file " + filename); } return null; } public static void deleteFile(String filename) { File f = new File(context.getCacheDir() + "/" + filename); if (f.canRead()) { f.delete(); } } public static void clearFileCache(ArrayList<String> exceptionFilenames) { File dir = context.getCacheDir(); if (dir != null && dir.isDirectory()) { try { for (File children : dir.listFiles()) { Log.d("FileStorage", "checking " + children.getName()); if (exceptionFilenames != null && !exceptionFilenames.contains(children.getName())) { Log.d("FileStorage", "Deleting unbound file " + children.getName()); children.delete(); } } } catch (Exception e) { Log.e("FileStorage", "failed to clean cache", e); } } } public static void setContext(Context c) { context = c; } }
//package com.nauj27.android.colorpicker; import java.util.Iterator; import java.util.List; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; import android.hardware.Camera; import android.hardware.Camera.Size; import android.view.View; import android.widget.ImageView; /** * @author nauj27 * */ class Utils { /** * Fill hex string with "0" when hexString minor than F. * @param hexString * @return */ public static String beautyHexString(String hexString) { if (hexString.length() < 2) { return "0".concat(hexString); } else { return hexString; } } /** * Find components of color of the bitmap at x, y. * @param x Distance from left border of the View * @param y Distance from top of the View * @param view Touched surface on screen */ public static int findColor(View view, int x, int y) throws NullPointerException { int red = 0; int green = 0; int blue = 0; int color = 0; int offset = 1; // 3x3 Matrix int pixelsNumber = 0; int xImage = 0; int yImage = 0; // Get the bitmap from the view. ImageView imageView = (ImageView)view; BitmapDrawable bitmapDrawable = (BitmapDrawable)imageView.getDrawable(); Bitmap imageBitmap = bitmapDrawable.getBitmap(); // Calculate the target in the bitmap. xImage = (int)(x * ((double)imageBitmap.getWidth() / (double)imageView.getWidth())); yImage = (int)(y * ((double)imageBitmap.getHeight() / (double)imageView.getHeight())); // Average of pixels color around the center of the touch. for (int i = xImage - offset; i <= xImage + offset; i++) { for (int j = yImage - offset; j <= yImage + offset; j++) { try { color = imageBitmap.getPixel(i, j); red += Color.red(color); green += Color.green(color); blue += Color.blue(color); pixelsNumber += 1; } catch(Exception e) { //Log.w(TAG, "Error picking color!"); } } } red = red / pixelsNumber; green = green / pixelsNumber; blue = blue / pixelsNumber; return Color.rgb(red, green, blue); } }
get Bitmap From Url
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; class IOUtils { private static final String LOG_TAG = "IOUtils"; public static final String PREFS_FILE = "javaeye.prefs"; public static Bitmap getBitmapFromUrl(URL url) { Bitmap bitmap = null; InputStream in = null; OutputStream out = null; try { in = new BufferedInputStream(url.openStream(), 4 * 1024); final ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); out = new BufferedOutputStream(dataStream, 4 * 1024); copy(in, out); out.flush(); final byte[] data = dataStream.toByteArray(); bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); // Log.e(LOG_TAG, "bitmap returning something"); return bitmap; } catch (IOException e) { // Log.e(LOG_TAG, e.getMessage()); } finally { closeStream(in); closeStream(out); } // Log.e(LOG_TAG, "bitmap returning null"); return null; } private static void copy(InputStream in, OutputStream out) throws IOException { byte[] b = new byte[4 * 1024]; int read; while ((read = in.read(b)) != -1) { out.write(b, 0, read); } } private static void closeStream(Closeable stream) { if (stream != null) { try { stream.close(); } catch (IOException e) { // Log.e(LOG_TAG, e.getMessage()); } } } }
Draw Bitmap and Drawable
import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Bitmap.Config; public class BitmapUtils { public static int BACKGROUND_COLOR = Color.argb(255, 128, 128, 128); private static int LINE_COLOR = Color.argb(255, 154,154,154); public static Bitmap drawBackground(int cellSize, int height, int widht) { Bitmap bitmap = Bitmap.createBitmap(widht, height, Config.ARGB_8888); Canvas cv = new Canvas(bitmap); Paint background = new Paint(); background.setColor(BACKGROUND_COLOR); cv.drawRect(0, 0, widht, height, background); background.setAntiAlias(true); background.setColor(LINE_COLOR); for (int i = 0; i < widht / cellSize; i++) { cv.drawLine(cellSize * i, 0, cellSize * i, height, background); } for (int i = 0; i < height / cellSize; i++) { cv.drawLine(0, cellSize * i, widht, cellSize * i, background); } return bitmap; } public static Bitmap drawEmptyBackground(int size){ Bitmap bitmap = Bitmap.createBitmap(size, size, Config.RGB_565); Canvas cv = new Canvas(bitmap); Paint background = new Paint(); background.setColor(BACKGROUND_COLOR); cv.drawRect(0, 0, size, size, background); return bitmap; } }
Rotate, transform Bitmap
//package com.birbeck.wallpaperslideshow; import java.io.File; import java.io.FileFilter; import java.util.Collection; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Rect; import android.util.Log; /** * Collection of utility functions used in this package. */ public class BitmapUtil { public static final int UNCONSTRAINED = -1; private static final String TAG = "BitmapUtil"; public BitmapUtil() { } // Rotates the bitmap by the specified degree. // If a new bitmap is created, the original bitmap is recycled. public static Bitmap rotate(Bitmap b, int degrees, Matrix m) { if (degrees != 0 && b != null) { if (m == null) { m = new Matrix(); } m.setRotate(degrees, (float) b.getWidth() / 2, (float) b.getHeight() / 2); try { Bitmap b2 = Bitmap.createBitmap( b, 0, 0, b.getWidth(), b.getHeight(), m, true); if (b != b2) { b.recycle(); b = b2; } } catch (OutOfMemoryError ex) { // We have no memory to rotate. Return the original bitmap. Log.e(TAG, "Got oom exception ", ex); } } return b; } /* * Compute the sample size as a function of minSideLength * and maxNumOfPixels. * minSideLength is used to specify that minimal width or height of a * bitmap. * maxNumOfPixels is used to specify the maximal size in pixels that is * tolerable in terms of memory usage. * * The function returns a sample size based on the constraints. * Both size and minSideLength can be passed in as IImage.UNCONSTRAINED, * which indicates no care of the corresponding constraint. * The functions prefers returning a sample size that * generates a smaller bitmap, unless minSideLength = IImage.UNCONSTRAINED. * * Also, the function rounds up the sample size to a power of 2 or multiple * of 8 because BitmapFactory only honors sample size this way. * For example, BitmapFactory downsamples an image by 2 even though the * request is 3. So we round up the sample size to avoid OOM. */ public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) { int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels); int roundedSize; if (initialSize <= 8) { roundedSize = 1; while (roundedSize < initialSize) { roundedSize <<= 1; } } else { roundedSize = (initialSize + 7) / 8 * 8; } return roundedSize; } private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) { double w = options.outWidth; double h = options.outHeight; int lowerBound = (maxNumOfPixels == UNCONSTRAINED) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels)); int upperBound = (minSideLength == UNCONSTRAINED) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength)); if (upperBound < lowerBound) { // return the larger one when there is no overlapping zone. return lowerBound; } if ((maxNumOfPixels == UNCONSTRAINED) && (minSideLength == UNCONSTRAINED)) { return 1; } else if (minSideLength == UNCONSTRAINED) { return lowerBound; } else { return upperBound; } } public static Bitmap transform(Matrix scaler, Bitmap source, int targetWidth, int targetHeight, boolean scaleUp, boolean recycle) { 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); if (recycle) { source.recycle(); } 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; } if (recycle && b1 != source) { source.recycle(); } 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 (b2 != b1) { if (recycle || b1 != source) { b1.recycle(); } } return b2; } /** * Make a bitmap from a given Uri. * * @param uri */ public static Bitmap makeBitmap(int minSideLength, int maxNumOfPixels, String pathName, BitmapFactory.Options options) { try { if (options == null) options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(pathName, options); if (options.mCancel || options.outWidth == -1 || options.outHeight == -1) { return null; } options.inSampleSize = computeSampleSize( options, minSideLength, maxNumOfPixels); options.inJustDecodeBounds = false; //options.inDither = false; //options.inPreferredConfig = Bitmap.Config.ARGB_8888; return BitmapFactory.decodeFile(pathName, options); } catch (OutOfMemoryError ex) { Log.e(TAG, "Got oom exception ", ex); return null; } } public static String getExtension(String name) { String ext = null; int i = name.lastIndexOf('.'); if (i > 0 && i < name.length() - 1) { ext = name.substring(i+1).toLowerCase(); } return ext; } public static File[] listFiles(File directory, boolean recurse, FileFilter filter) { if (!recurse) { return directory.listFiles(filter); } else { Collection<File> mFiles = new java.util.LinkedList<File>(); innerListFiles(mFiles, directory, filter); return (File[]) mFiles.toArray(new File[mFiles.size()]); } } public static void innerListFiles(Collection<File> files, File directory, FileFilter filter) { File[] found = directory.listFiles(); if (found != null) { for (int i = 0; i < found.length; i++) { if (found[i].isDirectory()) { innerListFiles(files, found[i], filter); } else { File[] found2 = directory.listFiles((FileFilter) filter); for (int j = 0; j < found2.length; j++) { files.add(found2[j]); } } } } } }
//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; } }
package com.google.android.panoramio; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Log; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; /** * Utilities for loading a bitmap from a URL * */ public class BitmapUtils { private static final String TAG = "Panoramio"; private static final int IO_BUFFER_SIZE = 4 * 1024; /** * Loads a bitmap from the specified url. This can take a while, so it should not * be called from the UI thread. * * @param url The location of the bitmap asset * * @return The bitmap, or null if it could not be loaded */ public static Bitmap loadBitmap(String url) { Bitmap bitmap = null; InputStream in = null; BufferedOutputStream out = null; try { in = new BufferedInputStream(new URL(url).openStream(), IO_BUFFER_SIZE); final ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE); copy(in, out); out.flush(); final byte[] data = dataStream.toByteArray(); bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); } catch (IOException e) { Log.e(TAG, "Could not load Bitmap from: " + url); } finally { closeStream(in); closeStream(out); } return bitmap; } /** * Closes the specified stream. * * @param stream The stream to close. */ private static void closeStream(Closeable stream) { if (stream != null) { try { stream.close(); } catch (IOException e) { android.util.Log.e(TAG, "Could not close stream", e); } } } /** * Copy the content of the input stream into the output stream, using a * temporary byte array buffer whose size is defined by * {@link #IO_BUFFER_SIZE}. * * @param in The input stream to copy from. * @param out The output stream to copy to. * @throws IOException If any error occurs during the copy. */ private static void copy(InputStream in, OutputStream out) throws IOException { byte[] b = new byte[IO_BUFFER_SIZE]; int read; while ((read = in.read(b)) != -1) { out.write(b, 0, read); } } }
Bitmap Refelection
//package com.gueei.demos.fbUpload; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.LinearGradient; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Shader.TileMode; // Source from http://androidsnips.blogspot.com/2010/08/showing-image-with-reflection-in.html class Utility { public static Bitmap getRefelection(Bitmap image) { //The gap we want between the reflection and the original image final int reflectionGap = 4; //Get you bit map from drawable folder Bitmap originalImage = image ; int width = originalImage.getWidth(); int height = originalImage.getHeight(); //This will not scale but will flip on the Y axis Matrix matrix = new Matrix(); matrix.preScale(1, -1); //Create a Bitmap with the flip matix applied to it. //We only want the bottom half of the image Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, height/2, width, height/2, matrix, false); //Create a new bitmap with same width but taller to fit reflection Bitmap bitmapWithReflection = Bitmap.createBitmap(width , (height + height/2), Config.ARGB_8888); //Create a new Canvas with the bitmap that's big enough for //the image plus gap plus reflection Canvas canvas = new Canvas(bitmapWithReflection); //Draw in the original image canvas.drawBitmap(originalImage, 0, 0, null); //Draw in the gap Paint deafaultPaint = new Paint(); canvas.drawRect(0, height, width, height + reflectionGap, deafaultPaint); //Draw in the reflection canvas.drawBitmap(reflectionImage,0, height + reflectionGap, null); //Create a shader that is a linear gradient that covers the reflection Paint paint = new Paint(); LinearGradient shader = new LinearGradient(0, originalImage.getHeight(), 0, bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP); //Set the paint to use this shader (linear gradient) paint.setShader(shader); //Set the Transfer mode to be porter duff and destination in paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN)); //Draw a rectangle using the paint with our linear gradient canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint); reflectionImage.recycle(); return bitmapWithReflection; } }
Create a transparent bitmap from an existing bitmap by replacing certain color with transparent
//package org.dyndns.warenix.util; import android.graphics.Bitmap; import android.graphics.Color; class Main{ /** * create a transparent bitmap from an existing bitmap by replacing certain * color with transparent * * @param bitmap * the original bitmap with a color you want to replace * @return a replaced color immutable bitmap */ public static Bitmap createTransparentBitmapFromBitmap(Bitmap bitmap, int replaceThisColor) { if (bitmap != null) { int picw = bitmap.getWidth(); int pich = bitmap.getHeight(); int[] pix = new int[picw * pich]; bitmap.getPixels(pix, 0, picw, 0, 0, picw, pich); for (int y = 0; y < pich; y++) { // from left to right for (int x = 0; x < picw; x++) { int index = y * picw + x; int r = (pix[index] >> 16) & 0xff; int g = (pix[index] >> 8) & 0xff; int b = pix[index] & 0xff; if (pix[index] == replaceThisColor) { pix[index] = Color.TRANSPARENT; } else { break; } } // from right to left for (int x = picw - 1; x >= 0; x--) { int index = y * picw + x; int r = (pix[index] >> 16) & 0xff; int g = (pix[index] >> 8) & 0xff; int b = pix[index] & 0xff; if (pix[index] == replaceThisColor) { pix[index] = Color.TRANSPARENT; } else { break; } } } Bitmap bm = Bitmap.createBitmap(pix, picw, pich, Bitmap.Config.ARGB_4444); return bm; } return null; } } InputStream Utils /* Copyright 2010 Cesar Valiente Gordo This file is part of QuiteSleep. QuiteSleep is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QuiteSleep is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QuiteSleep. If not, see <http://www.gnu.org/licenses/>. */ package es.cesar.quitesleep.utils; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; public class InputStreamUtils { final static int BUFFER_SIZE = 4096; // Tama??e los bloques a leer/escribir al comprimir en ZIP public static String InputStreamTOString (InputStream in) throws Exception { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] data = new byte[BUFFER_SIZE]; int count = -1; // Bytes leidos por bloque while ( (count = in.read(data,0,BUFFER_SIZE)) != -1 ) outStream.write(data,0,count); data=null; return new String (outStream.toByteArray(),"ISO-8859-1"); } public static String InputStreamTOString (InputStream in, String encoding) throws Exception { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] data = new byte[BUFFER_SIZE]; int count = -1; // Bytes leidos por bloque while ( (count = in.read(data,0,BUFFER_SIZE)) != -1 ) outStream.write(data,0,count); data=null; return new String (outStream.toByteArray(),encoding); *************************************************************************/ public static InputStream StringTOInputStream (String in) throws Exception { ByteArrayInputStream is = new ByteArrayInputStream(in.getBytes("ISO-8859-1")); return is; } public static byte[] InputStreamTOByte (InputStream in) throws IOException { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] data = new byte[BUFFER_SIZE]; int count = -1; // Bytes leidos por bloque while ( (count = in.read(data,0,BUFFER_SIZE)) != -1 ) outStream.write(data,0,count); data=null; return outStream.toByteArray(); } public static InputStream byteTOInputStream (byte[] in) throws Exception { ByteArrayInputStream resultado = new ByteArrayInputStream(in); return resultado; } public static String byteToString (byte[] in) throws Exception { InputStream ins = byteTOInputStream(in); return InputStreamTOString(ins); } }
Get Texture From Bitmap Resource
import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; final class Utils { private static Matrix yFlipMatrix; static { yFlipMatrix = new Matrix(); yFlipMatrix.postScale(-1, 1); // flip Y axis } public static Bitmap getTextureFromBitmapResource(Context context, int resourceId) { Bitmap bitmap = null; try { bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId); return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), yFlipMatrix, false); } finally { if (bitmap != null) { bitmap.recycle(); } } } }
Bitmap Resize
import android.graphics.Bitmap; import android.graphics.Matrix; import android.util.Log; public class BitmapResizer { public static Bitmap resizeImage(Bitmap image, int maxWidth, int maxHeight) { int imageWidth = image.getWidth(); int imageHeight = image.getHeight(); double imageAspect = (double) imageWidth / imageHeight; double canvasAspect = (double) maxWidth / maxHeight; double scaleFactor; if (imageAspect < canvasAspect) { scaleFactor = (double) maxHeight / imageHeight; } else { scaleFactor = (double) maxWidth / imageWidth; } float scaleWidth = ((float) scaleFactor) * imageWidth; float scaleHeight = ((float) scaleFactor) * imageHeight; // create a matrix for the manipulation Matrix matrix = new Matrix(); // resize the bit map matrix.postScale(scaleWidth, scaleHeight); // recreate the new Bitmap return Bitmap.createScaledBitmap(image, (int) scaleWidth, (int) scaleHeight, true); } }
bitmap to Byte
import java.io.ByteArrayOutputStream; import android.graphics.Bitmap; class Main { /** * Bitmapto byte. * * @param bitmap * the bitmap * @return the byte[] */ public static byte[] bitmaptoByte(Bitmap bitmap) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 90, baos); byte[] data = baos.toByteArray(); return data; } }
Flip Image
package app.test; import java.io.FileNotFoundException; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.Display; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class Test extends Activity implements OnClickListener { ImageView chosenImageView; Button choosePicture; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); chosenImageView = (ImageView) this.findViewById(R.id.ChosenImageView); choosePicture = (Button) this.findViewById(R.id.ChoosePictureButton); choosePicture.setOnClickListener(this); } public void onClick(View v) { Intent choosePictureIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(choosePictureIntent, 0); } protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); if (resultCode == RESULT_OK) { Uri imageFileUri = intent.getData(); Display currentDisplay = getWindowManager().getDefaultDisplay(); int dw = currentDisplay.getWidth(); int dh = currentDisplay.getHeight() / 2 - 100; try { BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream( imageFileUri), null, bmpFactoryOptions); bmpFactoryOptions.inSampleSize = 2; bmpFactoryOptions.inJustDecodeBounds = false; bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream( imageFileUri), null, bmpFactoryOptions); Bitmap alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp .getHeight(), bmp.getConfig()); Canvas canvas = new Canvas(alteredBitmap); Paint paint = new Paint(); Matrix matrix = new Matrix(); // Flip matrix.setScale(1, -1); matrix.postTranslate(0, bmp.getHeight()); canvas.drawBitmap(bmp, matrix, paint); ImageView alteredImageView = (ImageView) this.findViewById(R.id.AlteredImageView); alteredImageView.setImageBitmap(alteredBitmap); chosenImageView.setImageBitmap(bmp); } catch (Exception e) { Log.v("ERROR", e.toString()); } } } } //main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Choose Picture" android:id="@+id/ChoosePictureButton"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/ChosenImageView"></ImageView> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/AlteredImageView"></ImageView> </LinearLayout>
Scale an Image
package app.test; import java.io.FileNotFoundException; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.Display; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class Test extends Activity implements OnClickListener { ImageView chosenImageView; Button choosePicture; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); chosenImageView = (ImageView) this.findViewById(R.id.ChosenImageView); choosePicture = (Button) this.findViewById(R.id.ChoosePictureButton); choosePicture.setOnClickListener(this); } public void onClick(View v) { Intent choosePictureIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(choosePictureIntent, 0); } protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); if (resultCode == RESULT_OK) { Uri imageFileUri = intent.getData(); Display currentDisplay = getWindowManager().getDefaultDisplay(); int dw = currentDisplay.getWidth(); int dh = currentDisplay.getHeight() / 2 - 100; try { BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream( imageFileUri), null, bmpFactoryOptions); bmpFactoryOptions.inSampleSize = 2; bmpFactoryOptions.inJustDecodeBounds = false; bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream( imageFileUri), null, bmpFactoryOptions); Bitmap alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp .getHeight(), bmp.getConfig()); Canvas canvas = new Canvas(alteredBitmap); Paint paint = new Paint(); Matrix matrix = new Matrix(); // Scale matrix.setScale(1.5f,1); canvas.drawBitmap(bmp, matrix, paint); ImageView alteredImageView = (ImageView) this.findViewById(R.id.AlteredImageView); alteredImageView.setImageBitmap(alteredBitmap); chosenImageView.setImageBitmap(bmp); } catch (Exception e) { Log.v("ERROR", e.toString()); } } } } //main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Choose Picture" android:id="@+id/ChoosePictureButton"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/ChosenImageView"></ImageView> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/AlteredImageView"></ImageView> </LinearLayout>
Translate Image
package app.test; import java.io.FileNotFoundException; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.Display; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class Test extends Activity implements OnClickListener { ImageView chosenImageView; Button choosePicture; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); chosenImageView = (ImageView) this.findViewById(R.id.ChosenImageView); choosePicture = (Button) this.findViewById(R.id.ChoosePictureButton); choosePicture.setOnClickListener(this); } public void onClick(View v) { Intent choosePictureIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(choosePictureIntent, 0); } protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); if (resultCode == RESULT_OK) { Uri imageFileUri = intent.getData(); Display currentDisplay = getWindowManager().getDefaultDisplay(); int dw = currentDisplay.getWidth(); int dh = currentDisplay.getHeight() / 2 - 100; try { BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream( imageFileUri), null, bmpFactoryOptions); bmpFactoryOptions.inSampleSize = 2; bmpFactoryOptions.inJustDecodeBounds = false; bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream( imageFileUri), null, bmpFactoryOptions); Bitmap alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp .getHeight(), bmp.getConfig()); Canvas canvas = new Canvas(alteredBitmap); Paint paint = new Paint(); Matrix matrix = new Matrix(); // Translate matrix.setTranslate(1.5f,-10); canvas.drawBitmap(bmp, matrix, paint); ImageView alteredImageView = (ImageView) this.findViewById(R.id.AlteredImageView); alteredImageView.setImageBitmap(alteredBitmap); chosenImageView.setImageBitmap(bmp); } catch (Exception e) { Log.v("ERROR", e.toString()); } } } } //main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Choose Picture" android:id="@+id/ChoosePictureButton"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/ChosenImageView"></ImageView> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/AlteredImageView"></ImageView> </LinearLayout>
Image Mirror
package app.test; import java.io.FileNotFoundException; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.Display; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class Test extends Activity implements OnClickListener { ImageView chosenImageView; Button choosePicture; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); chosenImageView = (ImageView) this.findViewById(R.id.ChosenImageView); choosePicture = (Button) this.findViewById(R.id.ChoosePictureButton); choosePicture.setOnClickListener(this); } public void onClick(View v) { Intent choosePictureIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(choosePictureIntent, 0); } protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); if (resultCode == RESULT_OK) { Uri imageFileUri = intent.getData(); Display currentDisplay = getWindowManager().getDefaultDisplay(); int dw = currentDisplay.getWidth(); int dh = currentDisplay.getHeight() / 2 - 100; try { BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream( imageFileUri), null, bmpFactoryOptions); bmpFactoryOptions.inSampleSize = 2; bmpFactoryOptions.inJustDecodeBounds = false; bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream( imageFileUri), null, bmpFactoryOptions); Bitmap alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp .getHeight(), bmp.getConfig()); Canvas canvas = new Canvas(alteredBitmap); Paint paint = new Paint(); Matrix matrix = new Matrix(); // Mirror matrix.setScale(-1, 1); matrix.postTranslate(bmp.getWidth(),0); canvas.drawBitmap(bmp, matrix, paint); ImageView alteredImageView = (ImageView) this.findViewById(R.id.AlteredImageView); alteredImageView.setImageBitmap(alteredBitmap); chosenImageView.setImageBitmap(bmp); } catch (Exception e) { Log.v("ERROR", e.toString()); } } } } //main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Choose Picture" android:id="@+id/ChoosePictureButton"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/ChosenImageView"></ImageView> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/AlteredImageView"></ImageView> </LinearLayout>
Moving an Image with Motion
package app.test; import java.io.FileNotFoundException; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.Display; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.widget.Button; import android.widget.ImageView; public class Test extends Activity implements OnClickListener, OnTouchListener { ImageView choosenImageView; Button choosePicture; Bitmap bmp; Bitmap alteredBitmap; Canvas canvas; Paint paint; Matrix matrix; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); choosenImageView = (ImageView) this.findViewById(R.id.ChoosenImageView); choosePicture = (Button) this.findViewById(R.id.ChoosePictureButton); choosePicture.setOnClickListener(this); choosenImageView.setOnTouchListener(this); } public void onClick(View v) { Intent choosePictureIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(choosePictureIntent, 0); } protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); if (resultCode == RESULT_OK) { Uri imageFileUri = intent.getData(); try { BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inJustDecodeBounds = true; bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream( imageFileUri), null, bmpFactoryOptions); bmpFactoryOptions.inSampleSize = 2; bmpFactoryOptions.inJustDecodeBounds = false; bmp = BitmapFactory .decodeStream(getContentResolver().openInputStream( imageFileUri), null, bmpFactoryOptions); alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp .getHeight(), bmp.getConfig()); canvas = new Canvas(alteredBitmap); paint = new Paint(); paint.setColor(Color.GREEN); paint.setStrokeWidth(5); matrix = new Matrix(); canvas.drawBitmap(bmp, matrix, paint); choosenImageView.setImageBitmap(alteredBitmap); choosenImageView.setOnTouchListener(this); } catch (Exception e) { Log.v("ERROR", e.toString()); } } } float downx = 0; float downy = 0; float upx = 0; float upy = 0; public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: downx = event.getX(); downy = event.getY(); break; case MotionEvent.ACTION_MOVE: upx = event.getX(); upy = event.getY(); canvas.drawLine(downx, downy, upx, upy, paint); choosenImageView.invalidate(); downx = upx; downy = upy; break; case MotionEvent.ACTION_UP: upx = event.getX(); upy = event.getY(); canvas.drawLine(downx, downy, upx, upy, paint); choosenImageView.invalidate(); break; case MotionEvent.ACTION_CANCEL: break; default: break; } return true; } }
Draw on Picture and save
package app.test; import java.io.FileNotFoundException; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.Display; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.widget.Button; import android.widget.ImageView; import java.io.OutputStream; import android.content.ContentValues; import android.graphics.Bitmap.CompressFormat; import android.provider.MediaStore.Images.Media; import android.widget.Toast; public class Test extends Activity implements OnClickListener, OnTouchListener { ImageView choosenImageView; Button choosePicture; Button savePicture; Bitmap bmp; Bitmap alteredBitmap; Canvas canvas; Paint paint; Matrix matrix; float downx = 0; float downy = 0; float upx = 0; float upy = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); choosenImageView = (ImageView) this.findViewById(R.id.ChoosenImageView); choosePicture = (Button) this.findViewById(R.id.ChoosePictureButton); savePicture = (Button) this.findViewById(R.id.SavePictureButton); savePicture.setOnClickListener(this); choosePicture.setOnClickListener(this); choosenImageView.setOnTouchListener(this); } public void onClick(View v) { if (v == choosePicture) { Intent choosePictureIntent = new Intent( Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(choosePictureIntent, 0); } else if (v == savePicture) { if (alteredBitmap != null) { ContentValues contentValues = new ContentValues(3); contentValues.put(Media.DISPLAY_NAME, "Draw On Me"); Uri imageFileUri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, contentValues); try { OutputStream imageFileOS = getContentResolver().openOutputStream(imageFileUri); alteredBitmap.compress(CompressFormat.JPEG, 90, imageFileOS); Toast t = Toast.makeText(this, "Saved!", Toast.LENGTH_SHORT); t.show(); } catch (Exception e) { Log.v("EXCEPTION", e.getMessage()); } } } } protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); if (resultCode == RESULT_OK) { Uri imageFileUri = intent.getData(); try { BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inJustDecodeBounds = true; bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream( imageFileUri), null, bmpFactoryOptions); bmpFactoryOptions.inJustDecodeBounds = false; bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream( imageFileUri), null, bmpFactoryOptions); alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp .getHeight(), bmp.getConfig()); canvas = new Canvas(alteredBitmap); paint = new Paint(); paint.setColor(Color.GREEN); paint.setStrokeWidth(5); matrix = new Matrix(); canvas.drawBitmap(bmp, matrix, paint); choosenImageView.setImageBitmap(alteredBitmap); choosenImageView.setOnTouchListener(this); } catch (Exception e) { Log.v("ERROR", e.toString()); } } } public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: downx = event.getX(); downy = event.getY(); break; case MotionEvent.ACTION_MOVE: upx = event.getX(); upy = event.getY(); canvas.drawLine(downx, downy, upx, upy, paint); choosenImageView.invalidate(); downx = upx; downy = upy; break; case MotionEvent.ACTION_UP: upx = event.getX(); upy = event.getY(); canvas.drawLine(downx, downy, upx, upy, paint); choosenImageView.invalidate(); break; case MotionEvent.ACTION_CANCEL: break; default: break; } return true; } } //main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Choose Picture" android:id="@+id/ChoosePictureButton"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/ChoosenImageView"> </ImageView> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Save Picture" android:id="@+id/SavePictureButton"/> </LinearLayout>
Calculate optimal preview size from given parameters
//package org.andlib.helpers.image; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Map; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.hardware.Camera.Size; import android.view.View; final class ImageUtility { public static final int READ_BUFFER_SIZE = 32 * 1024; //32KB public static Bitmap getBitmapFromLocalPath(String path, int sampleSize) { try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = sampleSize; return BitmapFactory.decodeFile(path, options); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param bytes * @return */ public static Bitmap getBitmapFromBytes(byte[] bytes) { try { return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param bitmap * @param quality 1 ~ 100 * @return */ public static byte[] compressBitmap(Bitmap bitmap, int quality) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, quality, baos); return baos.toByteArray(); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * * @param srcBitmap * @param newWidth * @param newHeight * @return */ public static Bitmap getResizedBitmap(Bitmap srcBitmap, int newWidth, int newHeight) { try { return Bitmap.createScaledBitmap(srcBitmap, newWidth, newHeight, true); } catch(Exception e) { // Logger.e(e.toString()); } return null; } /** * captures given view and converts it to a bitmap * @param view * @return */ public static Bitmap captureViewToBitmap(View view) { Bitmap result = null; try { result = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.RGB_565); view.draw(new Canvas(result)); } catch(Exception e) { //Logger.e(e.toString()); } return result; } /** * * @param original * @param format * @param quality * @param outputLocation * @return */ public static boolean saveBitmap(Bitmap original, Bitmap.CompressFormat format, int quality, String outputLocation) { if(original == null) return false; try { return original.compress(format, quality, new FileOutputStream(outputLocation)); } catch(Exception e) { // Logger.e(e.toString()); } return false; } /** * * @param filepath * @param widthLimit * @param heightLimit * @param totalSize * @return */ public static Bitmap getResizedBitmap(String filepath, int widthLimit, int heightLimit, int totalSize) { int outWidth = 0; int outHeight = 0; int resize = 1; InputStream input = null; try { input = new FileInputStream(new File(filepath)); BitmapFactory.Options getSizeOpt = new BitmapFactory.Options(); getSizeOpt.inJustDecodeBounds = true; BitmapFactory.decodeStream(input, null, getSizeOpt); outWidth = getSizeOpt.outWidth; outHeight = getSizeOpt.outHeight; while((outWidth / resize) > widthLimit || (outHeight / resize) > heightLimit) { resize *= 2; } resize = resize * (totalSize + 15) / 15; BitmapFactory.Options resizeOpt = new BitmapFactory.Options(); resizeOpt.inSampleSize = resize; input.close(); input = null; input = new FileInputStream(new File(filepath)); Bitmap bitmapImage = BitmapFactory.decodeStream(input, null, resizeOpt); return bitmapImage; } catch(Exception e) { // Logger.e(e.toString()); } finally { if(input != null) { try { input.close(); } catch(IOException e) { // Logger.e(e.toString()); } } } return null; } public Bitmap getBlurredBitmap(Bitmap original, int radius) { if (radius < 1) return null; int width = original.getWidth(); int height = original.getHeight(); int wm = width - 1; int hm = height - 1; int wh = width * height; int div = radius + radius + 1; int r[] = new int[wh]; int g[] = new int[wh]; int b[] = new int[wh]; int rsum, gsum, bsum, x, y, i, p, p1, p2, yp, yi, yw; int vmin[] = new int[Math.max(width, height)]; int vmax[] = new int[Math.max(width,height)]; int dv[] = new int[256 * div]; for (i=0; i<256*div; i++) dv[i] = i / div; int[] blurredBitmap = new int[wh]; original.getPixels(blurredBitmap, 0, width, 0, 0, width, height); yw = 0; yi = 0; for (y=0; y<height; y++) { rsum = 0; gsum = 0; bsum = 0; for(i=-radius; i<=radius; i++) { p = blurredBitmap[yi + Math.min(wm, Math.max(i,0))]; rsum += (p & 0xff0000) >> 16; gsum += (p & 0x00ff00) >> 8; bsum += p & 0x0000ff; } for (x=0; x<width; x++) { r[yi] = dv[rsum]; g[yi] = dv[gsum]; b[yi] = dv[bsum]; if(y==0) { vmin[x] = Math.min(x + radius+1,wm); vmax[x] = Math.max(x - radius,0); } p1 = blurredBitmap[yw + vmin[x]]; p2 = blurredBitmap[yw + vmax[x]]; rsum += ((p1 & 0xff0000)-(p2 & 0xff0000))>>16; gsum += ((p1 & 0x00ff00)-(p2 & 0x00ff00))>>8; bsum += (p1 & 0x0000ff)-(p2 & 0x0000ff); yi ++; } yw += width; } for (x=0; x<width; x++) { rsum=gsum=bsum=0; yp =- radius * width; for(i=-radius; i<=radius; i++) { yi = Math.max(0,yp) + x; rsum += r[yi]; gsum += g[yi]; bsum += b[yi]; yp += width; } yi = x; for (y=0; y<height; y++) { blurredBitmap[yi] = 0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum]; if(x == 0) { vmin[y] = Math.min(y + radius + 1, hm) * width; vmax[y] = Math.max(y - radius, 0) * width; } p1 = x + vmin[y]; p2 = x + vmax[y]; rsum += r[p1] - r[p2]; gsum += g[p1] - g[p2]; bsum += b[p1] - b[p2]; yi += width; } } return Bitmap.createBitmap(blurredBitmap, width, height, Bitmap.Config.RGB_565); } public static Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.05; double targetRatio = (double) w / h; if (sizes == null) return null; Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; // Try to find an size match aspect ratio and size for (Size size : sizes) { double ratio = (double) size.width / size.height; if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } // Cannot find the one match the aspect ratio, ignore the requirement if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } return optimalSize; } }
generate Mipmaps For Bound Texture
import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.opengl.GLUtils; final class Utils { private static Matrix yFlipMatrix; static { yFlipMatrix = new Matrix(); yFlipMatrix.postScale(-1, 1); // flip Y axis } public static Bitmap getTextureFromBitmapResource(Context context, int resourceId) { Bitmap bitmap = null; try { bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId); return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), yFlipMatrix, false); } finally { if (bitmap != null) { bitmap.recycle(); } } } public static void generateMipmapsForBoundTexture(Bitmap texture) { // generate the full texture (mipmap level 0) GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture, 0); Bitmap currentMipmap = texture; int width = texture.getWidth(); int height = texture.getHeight(); int level = 0; boolean reachedLastLevel; do { // go to next mipmap level if (width > 1) width /= 2; if (height > 1) height /= 2; level++; reachedLastLevel = (width == 1 && height == 1); // generate next mipmap Bitmap mipmap = Bitmap.createScaledBitmap(currentMipmap, width, height, true); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, level, mipmap, 0); // recycle last mipmap (but don't recycle original texture) if (currentMipmap != texture) { currentMipmap.recycle(); } // remember last generated mipmap currentMipmap = mipmap; } while (!reachedLastLevel); // once again, recycle last mipmap (but don't recycle original texture) if (currentMipmap != texture) { currentMipmap.recycle(); } } }
Provides common tools for manipulating Bitmap objects
//package com.kg.emailalbum.mobile.util; import java.io.File; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Matrix; import android.net.Uri; import android.provider.MediaStore.Images; import android.util.DisplayMetrics; import android.util.Log; import android.view.WindowManager; /** * Provides common tools for manipulating Bitmap objects. * * @author Normal * */ public class BitmapUtil { private static DisplayMetrics mMetrics = null; private static final String LOG_TAG = BitmapUtil.class.getSimpleName(); private static Uri sStorageURI = Images.Media.EXTERNAL_CONTENT_URI; /** * Rotate a bitmap. * * @param bmp * A Bitmap of the picture. * @param degrees * Angle of the rotation, in degrees. * @return The rotated bitmap, constrained in the source bitmap dimensions. */ public static Bitmap rotate(Bitmap bmp, float degrees) { if (degrees % 360 != 0) { Log.d(LOG_TAG, "Rotating bitmap " + degrees + ""); Matrix rotMat = new Matrix(); rotMat.postRotate(degrees); if (bmp != null) { Bitmap dst = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp .getHeight(), rotMat, false); return dst; } } else { return bmp; } return null; } /** * Store a picture that has just been saved to disk in the MediaStore. * * @param imageFile * The File of the picture * @return The Uri provided by the MediaStore. */ public static Uri storePicture(Context ctx, File imageFile, String imageName) { ContentResolver cr = ctx.getContentResolver(); imageName = imageName.substring(imageName.lastIndexOf('/') + 1); ContentValues values = new ContentValues(7); values.put(Images.Media.TITLE, imageName); values.put(Images.Media.DISPLAY_NAME, imageName); values.put(Images.Media.DESCRIPTION, ""); values.put(Images.Media.DATE_TAKEN, System.currentTimeMillis()); values.put(Images.Media.MIME_TYPE, "image/jpeg"); values.put(Images.Media.ORIENTATION, 0); File parentFile = imageFile.getParentFile(); String path = parentFile.toString().toLowerCase(); String name = parentFile.getName().toLowerCase(); values.put(Images.ImageColumns.BUCKET_ID, path.hashCode()); values.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, name); values.put("_data", imageFile.toString()); Uri uri = cr.insert(sStorageURI, values); return uri; } public static Uri getContentUriFromFile(Context ctx, File imageFile) { Uri uri = null; ContentResolver cr = ctx.getContentResolver(); // Columns to return String[] projection = { Images.Media._ID, Images.Media.DATA }; // Look for a picture which matches with the requested path // (MediaStore stores the path in column Images.Media.DATA) String selection = Images.Media.DATA + " = ?"; String[] selArgs = { imageFile.toString() }; Cursor cursor = cr.query(sStorageURI, projection, selection, selArgs, null); if (cursor.moveToFirst()) { String id; int idColumn = cursor.getColumnIndex(Images.Media._ID); id = cursor.getString(idColumn); uri = Uri.withAppendedPath(sStorageURI, id); } cursor.close(); if (uri != null) { Log.d(LOG_TAG, "Found picture in MediaStore : " + imageFile.toString() + " is " + uri.toString()); } else { Log.d(LOG_TAG, "Did not find picture in MediaStore : " + imageFile.toString()); } return uri; } /** * @param ctx */ public static float getDensity(Context ctx) { if (mMetrics == null) { mMetrics = new DisplayMetrics(); ((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)) .getDefaultDisplay().getMetrics(mMetrics); } return mMetrics.density; } }