I'm very new to Android and want to create an image processing app.
I have lifted a code in using the camera of an android phone and shows the captured photo on a imageview... The code works well, the problem is that I can't seem to make the grayscaling code to work. Or I can't seem to show the grayscaled image on the imageview... Please I need your help. Thank you very much.
This is the camera image capturing code that works well
public class CameraActivity extends ActionBarActivity {
static final int REQUEST_IMAGE_CAPTURE = 1;
ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
Button button = (Button) findViewById(R.id.button);
//King ina, button2 for processing
Button button2 = (Button) findViewById(R.id.button2);
imageView = (ImageView) findViewById(R.id.imageView);
//Disable the button if it has no camera
if (!hasCamera())
button.setEnabled(false);
}
//Check if the user has camera
private boolean hasCamera() {
return getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
}
//Launching the camera
public void launchCamera(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//Take a picture and pass result along to onActivityResult
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}
//Show image on imageView
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
//Get the photo
Bundle extras = data.getExtras();
Bitmap image = (Bitmap) extras.get("data");
imageView.setImageBitmap(image);
}
}
}
While this is the code for Grayscaling the image... Can i just repeat the override code which shows the captured image?
Thanks a lot...
public Bitmap imageProcess(Bitmap image) {
int width, height;
height = image.getHeight();
width = image.getWidth();
Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(image, 0, 0, paint);
return bmpGrayscale;
}
Hi you can make the image black n white using contrast.
See the code..
public static Bitmap createContrast(Bitmap src, double value) {
// image size
int width = src.getWidth();
int height = src.getHeight();
// create output bitmap
Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
// color information
int A, R, G, B;
int pixel;
// get contrast value
double contrast = Math.pow((100 + value) / 100, 2);
// scan through all pixels
for(int x = 0; x < width; ++x) {
for(int y = 0; y < height; ++y) {
// get pixel color
pixel = src.getPixel(x, y);
A = Color.alpha(pixel);
// apply filter contrast for every channel R, G, B
R = Color.red(pixel);
R = (int)(((((R / 255.0) - 0.5) * contrast) + 0.5) * 255.0);
if(R < 0) { R = 0; }
else if(R > 255) { R = 255; }
G = Color.red(pixel);
G = (int)(((((G / 255.0) - 0.5) * contrast) + 0.5) * 255.0);
if(G < 0) { G = 0; }
else if(G > 255) { G = 255; }
B = Color.red(pixel);
B = (int)(((((B / 255.0) - 0.5) * contrast) + 0.5) * 255.0);
if(B < 0) { B = 0; }
else if(B > 255) { B = 255; }
// set new pixel color to output bitmap
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}
return bmOut;
}
Set the double value to 50 on mathod call. For Example
createContrast(Bitmap src, 50)
For more information on formulae please refer this
After researching and a few editing, I did the grayscaling this way...
bmp = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
operation = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
double GS_RED = 0.299;
double GS_GREEN = 0.587;
double GS_BLUE = 0.114;
int pixel;
int A, R, G, B;
// get image size
int width = bmp.getWidth();
int height = bmp.getHeight();
// scan through every single pixel
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
// get one pixel color
pixel = bmp.getPixel(x, y);
// retrieve color of all channels
A = Color.alpha(pixel);
R = Color.red(pixel);
G = Color.green(pixel);
B = Color.blue(pixel);
// take conversion up to one single value
R = G = B = (int) (GS_RED * R + GS_GREEN * G + GS_BLUE * B);
// set new pixel color to output bitmap
operation.setPixel(x, y, Color.argb(A, R, G, B));
//Show grayscaled image
imageView.setImageBitmap(operation);
}
}
Thanks for the answers and this site.
https://xjaphx.wordpress.com/2011/06/21/image-processing-grayscale-image-on-the-fly/
Use this dependency for image transformation
Github link - https://github.com/wasabeef/glide-transformations
repositories { mavenCentral()}
implementation 'jp.wasabeef:glide-transformations:4.3.0'
Glide.with(this).load(R.drawable.demo).apply(RequestOptions.bitmapTransform(GrayscaleTransformation())).into(imageView)
You need to call your imageProcess() method, before setting it in the image view.
//Show image on imageView
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
//Get the photo
Bundle extras = data.getExtras();
Bitmap image = (Bitmap) extras.get("data");
imageView.setImageBitmap(imageProcess(image)); // called here
}
}
Related
I'm working with an android studio project. I'm trying to select user touched pixel on an image, as shown Fig 1.
I want to add (X) on a pixel touched by the user, how can I make it by modifying bitmap ?
This is image.
If I understand your question correctly, you want to draw X in each time the user click on Bitmap, here's what you need :
ImageView img;
int clickCount = 0;
Bitmap src;
int colorTarget = Color.BLACK;
#SuppressLint("ClickableViewAccessibility")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img = findViewById(R.id.img);
img.setOnTouchListener((v, event) -> {
int x = (int) event.getX();
int y = (int) event.getY();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
drawXByPosition(img, src, x, y);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
clickCount++;
if (clickCount % 2 == 0) colorTarget = Color.BLACK;
else colorTarget = Color.WHITE;
}
return true;
});
}
private void drawXByPosition(ImageView iv, Bitmap bm, int x, int y) {
if (x < 0 || y < 0 || x > iv.getWidth() || y > iv.getHeight())
Toast.makeText(getApplicationContext(), "Outside of ImageView", Toast.LENGTH_SHORT).show();
else {
int projectedX = (int) ((double) x * ((double) bm.getWidth() / (double) iv.getWidth()));
int projectedY = (int) ((double) y * ((double) bm.getHeight() / (double) iv.getHeight()));
src = drawX(src, "X", 44, colorTarget, projectedX, projectedY);
img.setImageBitmap(src);
}
}
public Bitmap drawX(final Bitmap src,
final String content,
final float textSize,
#ColorInt final int color,
final float x,
final float y) {
Bitmap ret = src.copy(src.getConfig(), true);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Canvas canvas = new Canvas(ret);
paint.setColor(color);
paint.setTextSize(textSize);
Rect bounds = new Rect();
paint.getTextBounds(content, 0, content.length(), bounds);
canvas.drawText(content, x, y + textSize, paint);
return ret;
}
I knwo there is already an question like this. But its solution was not suitable for me because with the Sehellfolder Methode you can only get 16x16 and 32x32 sized icons.
I have extracted a HICO with size of 256x256 and want to convert it into and Java Image like BufferedImage. I found and method for it to. But it does not work properly:
public static BufferedImage getIcon(final WinDef.HICON hIcon,int ICON_SIZE,short ICON_DEPTH,int ICON_BYTE_SIZE) {
final int width = ICON_SIZE;
final int height = ICON_SIZE;
final short depth = ICON_DEPTH;
final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
final Memory lpBitsColor = new Memory(width * height * depth / ICON_BYTE_SIZE);
final Memory lpBitsMask = new Memory(width * height * depth / ICON_BYTE_SIZE);
final WinGDI.BITMAPINFO info = new WinGDI.BITMAPINFO();
final WinGDI.BITMAPINFOHEADER hdr = new WinGDI.BITMAPINFOHEADER();
info.bmiHeader = hdr;
hdr.biWidth = width;
hdr.biHeight = height;
hdr.biPlanes = 1;
hdr.biBitCount = depth;
hdr.biCompression = WinGDI.BI_RGB;
final WinDef.HDC hDC = User32.INSTANCE.GetDC(null);
final WinGDI.ICONINFO piconinfo = new WinGDI.ICONINFO();
User32.INSTANCE.GetIconInfo(hIcon, piconinfo);
GDI32.INSTANCE.GetDIBits(hDC, piconinfo.hbmColor, 0, height, lpBitsColor, info, WinGDI.DIB_RGB_COLORS);
GDI32.INSTANCE.GetDIBits(hDC, piconinfo.hbmMask, 0, height, lpBitsMask, info, WinGDI.DIB_RGB_COLORS);
int r, g, b, a, argb;
int x = 0, y = height - 1;
for (int i = 0; i < lpBitsColor.size(); i = i + 3) {
b = lpBitsColor.getByte(i) & 0xFF;
g = lpBitsColor.getByte(i + 1) & 0xFF;
r = lpBitsColor.getByte(i + 2) & 0xFF;
a = 0xFF - lpBitsMask.getByte(i) & 0xFF;
argb = a << 24 | r << 16 | g << 8 | b;
image.setRGB(x, y, argb);
x = (x + 1) % width;
if (x == 0) {
y--;
}
}
User32.INSTANCE.ReleaseDC(null, hDC);
GDI32.INSTANCE.DeleteObject(piconinfo.hbmColor);
GDI32.INSTANCE.DeleteObject(piconinfo.hbmMask);
return image;
}
Resulting Image
Do you know andy method that works better?
EDIT:
public static BufferedImage getImageByHICON(final int width, final int height, final WinNT.HANDLE hicon, final WinGDI.BITMAPINFOHEADER info) {
final WinGDI.ICONINFO iconinfo = new WinGDI.ICONINFO();
try {
// GDI32 g32 = GDI32.INSTANCE;
// get icon information
if (!User32.INSTANCE.GetIconInfo(new WinDef.HICON(hicon.getPointer()), iconinfo)) { return null; }
final WinDef.HWND hwdn = new WinDef.HWND();
final WinDef.HDC dc = User32.INSTANCE.GetDC(hwdn);
if (dc == null) {
return null; }
try {
final int nBits = width * height * 4;
// final BitmapInfo bmi = new BitmapInfo(1);
final Memory colorBitsMem = new Memory(nBits);
// // Extract the color bitmap
final WinGDI.BITMAPINFO bmi = new WinGDI.BITMAPINFO();
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = -height;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = WinGDI.BI_RGB;
GDI32.INSTANCE.GetDIBits(dc, iconinfo.hbmColor, 0, height, colorBitsMem, bmi, WinGDI.DIB_RGB_COLORS);
// g32.GetDIBits(dc, iconinfo.hbmColor, 0, size, colorBitsMem,
// bmi,
// GDI32.DIB_RGB_COLORS);
final int[] colorBits = colorBitsMem.getIntArray(0, width * height);
if (info.biBitCount < 32) {
final Memory maskBitsMem = new Memory(nBits);
// // Extract the mask bitmap
GDI32.INSTANCE.GetDIBits(dc, iconinfo.hbmMask, 0, height, maskBitsMem, bmi, WinGDI.DIB_PAL_COLORS);
// g32.GetDIBits(dc, iconinfo.hbmMask, 0, size,
// maskBitsMem,
// bmi,
// // GDI32.DIB_RGB_COLORS);
final int[] maskBits = maskBitsMem.getIntArray(0, width * height);
// // // Copy the mask alphas into the color bits
for (int i = 0; i < colorBits.length; i++) {
colorBits[i] = colorBits[i] | (maskBits[i] != 0 ? 0 : 0xFF000000);
}
}
final BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
bi.setRGB(0, 0, width, height, colorBits, 0, height);
return bi;
} finally {
com.sun.jna.platform.win32.User32.INSTANCE.ReleaseDC(hwdn, dc);
}
} finally {
User32.INSTANCE.DestroyIcon(new WinDef.HICON(hicon.getPointer()));
GDI32.INSTANCE.DeleteObject(iconinfo.hbmColor);
GDI32.INSTANCE.DeleteObject(iconinfo.hbmMask);
}
}
Better Image
You need to use the method from Example 3 from this website
I want to put a tensorflow model on Anroid.
I recently noticed that the results of running the same data in Python and Android, respectively, are inconsistent.
After several trial and error, I found that the input data I entered when I ran the model on Android was wrong.
It was just a java.lang.IllegalArgumentException error, and I think I put the data correctly, but I have no idea what went wrong.
I used images that were transformed into image resizing and gray scale as learning data. in Python
I did the same preprocessing on Android.
My image type is .jpg
I attached my source.
Source related to image preprocessing
btntrans.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
image_bitmap = resizeBitmapImage(image_bitmap, 28);
image_bitmap = RGB2GRAY(image_bitmap);
image.setImageBitmap(image_bitmap);
byte[] byteArrayRes = bitmapToByteArray(image_bitmap);
float[] inputArray = bytetofloat(byteArrayRes);
activityPrediction(inputArray);
}
catch(Exception e){
}
}
});
Everything happens when I click the button
resizeBitmapImage method
public Bitmap resizeBitmapImage(Bitmap source, int maxResolution)
{
int width = source.getWidth();
int height = source.getHeight();
int newWidth = width;
int newHeight = height;
float rate = 0.0f;
if(width > height)
{
if(maxResolution < width)
{
rate = maxResolution / (float) width;
newHeight = (int) (height * rate);
newWidth = maxResolution;
}
}
else
{
if(maxResolution < height)
{
rate = maxResolution / (float) height;
newWidth = (int) (width * rate);
newHeight = maxResolution;
}
}
return Bitmap.createScaledBitmap(source, newWidth, newHeight, true);
}
RGB2GRAY method
public Bitmap RGB2GRAY(Bitmap image){
int width = image.getWidth();
int height = image.getHeight();
Bitmap bmOut;
bmOut = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
for(int x = 0; x < width; x++){
for(int y = 0 ; y < height; y++){
int pixel = image.getPixel(x, y);
int A = Color.alpha(pixel);
int R = Color.red(pixel);
int G = Color.green(pixel);
int B = Color.blue(pixel);
R = G = B = (int)(0.299 * R + 0.587 * G + 0.114 * B);
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}
return bmOut;
}
bitmap to byte array method
private byte[] bitmapToByteArray(Bitmap bitmap){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
return stream.toByteArray();
}
bytetofloat method
public float[] bytetofloat(byte[] array){
int[] returnArr = new int[array.length/4];
float[] returnArr1 = new float[array.length/4];
for(int i = 0 ; i < returnArr.length; i++){
//array[i] = 0;
returnArr[i] = array[i*4] & 0xFF;
if(returnArr[i] < 0 || returnArr[i]>255)
Log.d("ARRAY", returnArr[i]+" ");
returnArr1[i] = (float)returnArr[i];
}
return returnArr1;
}
When I run it with the above source, I get this error exactly.
java.lang.IllegalArgumentException: buffer with 308 elements is not
compatible with a Tensor with shape [1, 28, 28]
28 * 28 is Input image size
Before image resizing, it had an average width of 20 and a height of 36.
The strange thing is that the number 308 is changed to 306, 307 and fixed.
What can i do?
Here is my method for converting Java BufferedImage to Tensor object:
private static Tensor<?> convertImageToArray(BufferedImage bf) {
int width = bf.getWidth();
int height = bf.getHeight();
float[][][][] rgbArray = new float[1][height][width][3];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
bf.getRaster().getPixel(i, j, rgbArray[0][i][j]);
}
}
return Tensor.create(rgbArray);
}
Your problem is probably in missed channels of your image. Float array length must be equal to
height * width * channels
of the image.
If i select some images it will work but when i select other images that maybe are more heavy in terms of size it gives me this error:
java.lang.OutOfMemoryError: Failed to allocate a 79629324 byte allocation with 16777120 free bytes and 46MB until OOM
I have this classes:
Main activity where i click to go to my custom gallery activity:
public class gallerygridselect extends BaseNavegationActivity implements View.OnClickListener{
private LinearLayout lnrImages;
private Button btnAddPhots,btnSaveImages;
private ArrayList<String> imagesPathList;
private Bitmap yourbitmap;
private final int PICK_IMAGE_MULTIPLE = 1;
ArrayList<String> a = new ArrayList<String>();
long imageSize = 0; // kb
ImageView imageView;
private String[] imagesPath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gallery_picker);
lnrImages = (LinearLayout) findViewById(R.id.lnrImages);
btnAddPhots = (Button) findViewById(R.id.btnAddPhots);
btnSaveImages = (Button) findViewById(R.id.btnSaveImages);
btnAddPhots.setOnClickListener(this);
btnSaveImages.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnAddPhots:
Intent intent = new Intent(gallerygridselect.this, gallerygrid.class);
startActivityForResult(intent, PICK_IMAGE_MULTIPLE);
break;
case R.id.btnSaveImages:
if (imagesPathList != null) {
if (imagesPathList.size() > 0) {
Toast.makeText(gallerygridselect.this, imagesPathList.size() + " fotos selecionadas", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(gallerygridselect.this, imagesPathList.size() + " fotos selecionadas", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(gallerygridselect.this, "Selecione as fotos", Toast.LENGTH_SHORT).show();
}
break;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == PICK_IMAGE_MULTIPLE) {
imagesPathList = new ArrayList<String>();
imagesPath = data.getStringExtra("data").split("\\|");
for (int i = 0; i < imagesPath.length; i++) {
System.out.println("imagesPath "+imagesPath[i]);
}
imageSize = this.getFileSize(String.valueOf(imagesPath));
Log.d("PATH", "" + imagesPath);
try {
lnrImages.removeAllViews();
} catch (Throwable e) {
e.printStackTrace();
}
for (int i = 0; i < imagesPath.length; i++) {
imagesPathList.add(imagesPath[i]);
Log.e("Pathlist", "" + imagesPathList);
yourbitmap = BitmapFactory.decodeFile(imagesPath[i]);
Log.i("BITMAP", "" + yourbitmap);
imageView = new ImageView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(5, 5, 5, 5);
imageView.setLayoutParams(params);
imageView.setImageBitmap(BitmapHelper.decodeFile(imagesPath[i], 320, 480, true));
imageView.setAdjustViewBounds(true);
lnrImages.addView(imageView);
}
}
}
}
private long getFileSize(String imagesPath) {
long length = 0;
try {
File file = new File(imagesPath);
length = file.length();
length = length / 1024;
} catch (Exception e) {
e.printStackTrace();
}
return length;
}
private String getPath(Uri uri) {
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
}
My bitmap help class:
public class BitmapHelper {
//decodes image and scales it to reduce memory consumption
public static Bitmap decodeFile(String bitmapFile, int requiredWidth, int requiredHeight, boolean quickAndDirty)
{
try
{
//Decode image size
BitmapFactory.Options bitmapSizeOptions = new BitmapFactory.Options();
bitmapSizeOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(bitmapFile), null, bitmapSizeOptions);
// load image using inSampleSize adapted to required image size
BitmapFactory.Options bitmapDecodeOptions = new BitmapFactory.Options();
bitmapDecodeOptions.inTempStorage = new byte[16 * 1024];
bitmapDecodeOptions.inSampleSize = computeInSampleSize(bitmapSizeOptions, requiredWidth, requiredHeight, false);
bitmapDecodeOptions.inPurgeable = true;
bitmapDecodeOptions.inDither = !quickAndDirty;
bitmapDecodeOptions.inPreferredConfig = quickAndDirty ? Bitmap.Config.RGB_565 : Bitmap.Config.ARGB_8888;
Bitmap decodedBitmap = BitmapFactory.decodeStream(new FileInputStream(bitmapFile), null, bitmapDecodeOptions);
// scale bitmap to mathc required size (and keep aspect ratio)
float srcWidth = (float) bitmapDecodeOptions.outWidth;
float srcHeight = (float) bitmapDecodeOptions.outHeight;
float dstWidth = (float) requiredWidth;
float dstHeight = (float) requiredHeight;
float srcAspectRatio = srcWidth / srcHeight;
float dstAspectRatio = dstWidth / dstHeight;
// recycleDecodedBitmap is used to know if we must recycle intermediary 'decodedBitmap'
// (DO NOT recycle it right away: wait for end of bitmap manipulation process to avoid
// java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap#416ee7d8
// I do not excatly understand why, but this way it's OK
boolean recycleDecodedBitmap = false;
Bitmap scaledBitmap = decodedBitmap;
if (srcAspectRatio < dstAspectRatio)
{
scaledBitmap = getScaledBitmap(decodedBitmap, (int) dstWidth, (int) (srcHeight * (dstWidth / srcWidth)));
// will recycle recycleDecodedBitmap
recycleDecodedBitmap = true;
}
else if (srcAspectRatio > dstAspectRatio)
{
scaledBitmap = getScaledBitmap(decodedBitmap, (int) (srcWidth * (dstHeight / srcHeight)), (int) dstHeight);
recycleDecodedBitmap = true;
}
// crop image to match required image size
int scaledBitmapWidth = scaledBitmap.getWidth();
int scaledBitmapHeight = scaledBitmap.getHeight();
Bitmap croppedBitmap = scaledBitmap;
if (scaledBitmapWidth > requiredWidth)
{
int xOffset = (scaledBitmapWidth - requiredWidth) / 2;
croppedBitmap = Bitmap.createBitmap(scaledBitmap, xOffset, 0, requiredWidth, requiredHeight);
scaledBitmap.recycle();
}
else if (scaledBitmapHeight > requiredHeight)
{
int yOffset = (scaledBitmapHeight - requiredHeight) / 2;
croppedBitmap = Bitmap.createBitmap(scaledBitmap, 0, yOffset, requiredWidth, requiredHeight);
scaledBitmap.recycle();
}
if (recycleDecodedBitmap)
{
decodedBitmap.recycle();
}
decodedBitmap = null;
scaledBitmap = null;
return croppedBitmap;
}
catch (Exception ex)
{
ex.printStackTrace();
}
return null;
}
/**
* compute powerOf2 or exact scale to be used as {#link BitmapFactory.Options#inSampleSize} value (for subSampling)
*
// #param requiredWidth
// #param requiredHeight
* #param powerOf2
* weither we want a power of 2 sclae or not
* #return
*/
public static int computeInSampleSize(BitmapFactory.Options options, int dstWidth, int dstHeight, boolean powerOf2)
{
int inSampleSize = 1;
// Raw height and width of image
final int srcHeight = options.outHeight;
final int srcWidth = options.outWidth;
if (powerOf2)
{
//Find the correct scale value. It should be the power of 2.
int tmpWidth = srcWidth, tmpHeight = srcHeight;
while (true)
{
if (tmpWidth / 2 < dstWidth || tmpHeight / 2 < dstHeight)
break;
tmpWidth /= 2;
tmpHeight /= 2;
inSampleSize *= 2;
}
}
else
{
// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) srcHeight / (float) dstHeight);
final int widthRatio = Math.round((float) srcWidth / (float) dstWidth);
// Choose the smallest ratio as inSampleSize value, this will guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
public static Bitmap drawableToBitmap(Drawable drawable)
{
if (drawable instanceof BitmapDrawable)
{
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
public static Bitmap getScaledBitmap(Bitmap bitmap, int newWidth, int newHeight)
{
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// RECREATE THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
}
Im newb at android development what can i do to fix this. Thanks in advance.
You need to pass file path with height and width. SO it will return you small image :-
Bitmap ShrinkBitmap(String file, int width, int height){
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);
int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);
if (heightRatio > 1 || widthRatio > 1)
{
if (heightRatio > widthRatio)
{
bmpFactoryOptions.inSampleSize = heightRatio;
} else {
bmpFactoryOptions.inSampleSize = widthRatio;
}
}
bmpFactoryOptions.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);
return bitmap;
}
for more info see link :-
http://voidcanvas.com/whatsapp-like-image-compression-in-android/
I'm creating a very simple app that changes a pictures color to a sepia filter when pressed. When I run the app everything works but it takes close to a minute for the image to change. Can you take a quick look at my code and see if you can tell me why?
public class Pictue extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pictue);
ImageButton button = (ImageButton) findViewById(R.id.imageButton1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Bitmap b1 = BitmapFactory.decodeResource(getResources(), R.drawable.chin);
b1 = createSepiaToningEffect(b1,10,7.00,6.00,3.00);
ImageView chin = (ImageView) findViewById(R.id.imageView1) ;
chin.setImageBitmap(b1);
}
});
}
public static Bitmap createSepiaToningEffect(Bitmap src, int depth, double red, double green, double blue) {
int width = src.getWidth();
int height = src.getHeight();
Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
final double GS_RED = 0.3;
final double GS_GREEN = 0.59;
final double GS_BLUE = 0.11;
int A, R, G, B;
int pixel;
for(int x = 0; x < width; ++x) {
for(int y = 0; y < height; ++y) {
pixel = src.getPixel(x, y);
A = Color.alpha(pixel);
R = Color.red(pixel);
G = Color.green(pixel);
B = Color.blue(pixel);
B = G = R = (int)(GS_RED * R + GS_GREEN * G + GS_BLUE * B);
// apply intensity level for sepid-toning on each channel
R += (depth * red);
if(R > 255) { R = 255; }
G += (depth * green);
if(G > 255) { G = 255; }
B += (depth * blue);
if(B > 255) { B = 255; }
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}
return bmOut;
}
}
i would suggest to use
Catalano framework as it was suggested here Loading image Effects taking Lot of time in Android?