I have this little problem. I wanna take a photo with my camera. After I take it I would like to save it at 640 x 640 pixels. So I shrink the size of the image of 5 MB to around 300 - 500 KB or less , but when I take the image with the camera it saves to my external storage but never converts it to 640 x 640. I get the original image size that is around 4k resolution.
The goal is to save inside a bitmap an image that is 640 x 640, but not the original size.
This is the code
public class MainActivity extends AppCompatActivity {
private static final String LOG_TAG = MainActivity.class.getSimpleName();
private static final int CAMERA_REQUEST_CODE = 1;
Button mBtnCamera;
private Uri imageUri = null;
int aleatorio;
String foto;
ImageView mImageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = (ImageView) findViewById(R.id.imageView);
aleatorio = Double.valueOf(Math.random() * 100).intValue();
foto = Environment.getExternalStorageDirectory() + "/imagen" + aleatorio + ".jpg";
mBtnCamera = (Button) findViewById(R.id.btnCamera);
mBtnCamera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cameraIntent();
}
});
}
private void cameraIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
imageUri = Uri.fromFile(new File(foto));
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(takePictureIntent, CAMERA_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST_CODE && resultCode == RESULT_OK) {
Bitmap image = BitmapFactory.decodeFile(foto);
Bitmap resizedBitmap = Bitmap.createScaledBitmap(
image, 640, 640, false);
File f = new File(foto);
long size = f.length();
Toast.makeText(this, size / (1024 * 1024) + " MB, " + f.getAbsolutePath(), Toast.LENGTH_LONG).show();
mImageView.setImageBitmap(resizedBitmap);
}
}
public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
int width = bm.getWidth();
int height = bm.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(
bm, 0, 0, width, height, matrix, false);
bm.recycle();
return resizedBitmap;
}
thanks
Your resizedBitmap object exist in the memory only in this situation. You should write that object to the storage.
Look at this solution:
MainActivity.java:
package szilard.sebok.myapplication;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
private static final String LOG_TAG = MainActivity.class.getSimpleName();
private static final int CAMERA_REQUEST_CODE = 1;
Button mBtnCamera;
private Uri imageUri = null;
int aleatorio;
String foto;
ImageView mImageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = (ImageView) findViewById(R.id.imageView);
aleatorio = Double.valueOf(Math.random() * 100).intValue();
foto = Environment.getExternalStorageDirectory() + "/imagen" + aleatorio + ".jpg";
mBtnCamera = (Button) findViewById(R.id.btnCamera);
mBtnCamera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cameraIntent();
}
});
}
private void cameraIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
imageUri = Uri.fromFile(new File(foto));
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(takePictureIntent, CAMERA_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST_CODE && resultCode == RESULT_OK) {
Bitmap image = BitmapFactory.decodeFile(foto);
Bitmap resizedBitmap = Bitmap.createScaledBitmap(image, 640, 640, false);
//Lets create a new file for resizedBitmap
// getExternalMediaDirs()[0].getPath() -> your first external media dir
// and adding the file name for that: ...mediadir + /filename.png
File resizedPng = new File(getExternalMediaDirs()[0].getPath() + "/resizedPng.png");
try {
//For testing I delete that if its exist
if (resizedPng.exists()) {
resizedPng.delete();
}
if (resizedPng.createNewFile()) {
//Try to write the resizedBitmap object to the path
boolean successfullWrite = writeResizedBitmapToFile(resizedBitmap, resizedPng.getPath());
if (successfullWrite) {
boolean deleted = tryToDeleOriginal(foto);
Toast.makeText(this, "WIN! Find your picture at: " + resizedPng.getPath() + "and is the original deleted? :" +String.valueOf(deleted), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Fail :(", Toast.LENGTH_LONG).show();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public boolean tryToDeleOriginal(String pathToOriginal){
File f = new File (pathToOriginal);
if (!f.isDirectory()){
if (f.exists()){
return f.delete();
}
}
return false;
}
//This one is from the post that I linked before
public boolean writeResizedBitmapToFile(Bitmap bmp, String filePath) {
FileOutputStream out = null;
try {
out = new FileOutputStream(filePath);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
return true;
}
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
int width = bm.getWidth();
int height = bm.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(
bm, 0, 0, width, height, matrix, false);
bm.recycle();
return resizedBitmap;
}
}
Don't forget the permessions at the manifest, add these:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Related
Hello Everyone I'm trying to create a pdf programatically from a set of images. I'm loading images on Listview from array list. after displaying the images on click floating action button I'm willing to create a new PDF file. I'm successfully creating file, Unfortunately I can able to see only one image on the pdf file out of 5 images. For reference purpose here I'm sharing the code which I'm trying to achieve. Please help me in creating and displaying list of images on PDF
import android.Manifest;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.graphics.pdf.PdfDocument;
import android.os.Build;
import android.os.Environment;
import android.support.annotation.RequiresApi;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.FileHandler;
public class DisplayPreview extends AppCompatActivity {
String TAG = DisplayPreview.class.getName();
ListView imagesLV;
FloatingActionButton fabPDF;
TextView tv_link;
ImageView iv_image;
LinearLayout ll_pdflayout;
public static int REQUEST_PERMISSIONS = 1;
boolean boolean_permission;
boolean boolean_save;
Bitmap bitmap;
ProgressDialog progressDialog;
ArrayList<String> selectedImagesList;
String targetPdf;
DisplayPreviewAdapter displayPreviewAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_preview);
Intent intent = getIntent();
selectedImagesList = intent.getStringArrayListExtra("selectedArray");
fn_permission();
imagesLV = findViewById(R.id.imagesLV);
displayPreviewAdapter = new DisplayPreviewAdapter(this, selectedImagesList);
imagesLV.setAdapter(displayPreviewAdapter);
fabPDF = findViewById(R.id.fabPDF);
fabPDF.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (boolean_save) {
Intent intent = new Intent(getApplicationContext(), PDFViewActivity.class);
intent.putExtra("pdfFile", targetPdf);
startActivity(intent);
} else {
if (boolean_permission) {
progressDialog = new ProgressDialog(DisplayPreview.this);
progressDialog.setMessage("Please wait");
bitmap = loadBitmapFromView(imagesLV, imagesLV.getWidth(), imagesLV.getHeight());
makePDF();
} else {
}
makePDF();
}
}
});
}
private void makePDF() {
DisplayMetrics displaymetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
float hight = displaymetrics.heightPixels;
float width = displaymetrics.widthPixels;
int convertHighet = (int) hight, convertWidth = (int) width;
// Resources mResources = getResources();
// Bitmap bitmap = BitmapFactory.decodeResource(mResources, R.drawable.img_1);
PdfDocument document = new PdfDocument();
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(convertWidth, convertHighet, 1).create();
PdfDocument.Page page = document.startPage(pageInfo);
Canvas canvas = page.getCanvas();
Paint paint = new Paint();
canvas.drawPaint(paint);
bitmap = Bitmap.createScaledBitmap(getBitmapFromView(imagesLV), convertWidth, convertHighet, true);
// bitmap = Bitmap.createScaledBitmap(bitmap, convertWidth, convertHighet, true);
paint.setColor(Color.BLUE);
canvas.drawBitmap(bitmap, 0, 0, null);
document.finishPage(page);
// write the document content
// String targetPdf = "/sdcard/test.pdf";
targetPdf = "mnt/sdcard/testing_1.pdf";
File filePath = new File(targetPdf);
try {
document.writeTo(new FileOutputStream(filePath));
boolean_save = true;
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "Something wrong: " + e.toString(), Toast.LENGTH_LONG).show();
}
// close the document
document.close();
}
public static Bitmap loadBitmapFromView(View v, int width, int height) {
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
public static Bitmap getBitmapFromView(View view) {
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null)
bgDrawable.draw(canvas);
else
canvas.drawColor(Color.WHITE);
view.draw(canvas);
return returnedBitmap;
}
private void fn_permission() {
if ((ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) ||
(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
if ((ActivityCompat.shouldShowRequestPermissionRationale(DisplayPreview.this, android.Manifest.permission.READ_EXTERNAL_STORAGE))) {
} else {
ActivityCompat.requestPermissions(DisplayPreview.this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSIONS);
}
if ((ActivityCompat.shouldShowRequestPermissionRationale(DisplayPreview.this, Manifest.permission.WRITE_EXTERNAL_STORAGE))) {
} else {
ActivityCompat.requestPermissions(DisplayPreview.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_PERMISSIONS);
}
} else {
boolean_permission = true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSIONS) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
boolean_permission = true;
} else {
Toast.makeText(getApplicationContext(), "Please allow the permission", Toast.LENGTH_LONG).show();
}
}
}
}
After hours of Struggle I found my own answer in creating multiple pages in a single PDF using android also image annotating with text here is the following source code
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
public class DisplayPreview extends AppCompatActivity {
String TAG = DisplayPreview.class.getName();
ListView imagesLV;
FloatingActionButton fabPDF;
Bitmap anImage;
TextView tv_link;
ImageView iv_image;
LinearLayout ll_pdflayout;
public static int REQUEST_PERMISSIONS = 1;
boolean boolean_permission;
boolean boolean_save;
Bitmap bitmap;
ProgressDialog progressDialog;
ArrayList<String> selectedImagesList;
String targetPdf;
DisplayPreviewAdapter displayPreviewAdapter;
String familyStatus, userNameStr;
public static final Integer[] IMAGES = {
R.drawable.img_1,
R.drawable.img_2,
R.drawable.img_3,
R.drawable.img_4,
R.drawable.img_5,
R.drawable.img_6,
R.drawable.img_7
// ,R.drawable.img_8,
// R.drawable.img_9
};
private ProgressDialog pDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_preview);
Intent intent = getIntent();
selectedImagesList = intent.getStringArrayListExtra("selectedArray");
familyStatus = intent.getStringExtra("familyStatus");
userNameStr = intent.getStringExtra("userNameStr");
targetPdf = "mnt/sdcard/testing_2.pdf";
imagesLV = findViewById(R.id.imagesLV);
displayPreviewAdapter = new DisplayPreviewAdapter(this, selectedImagesList, IMAGES);
// imagesLV.setAdapter(displayPreviewAdapter);
fabPDF = findViewById(R.id.fabPDF);
Drawable myDrawable = getResources().getDrawable(R.drawable.img_1);
anImage = ((BitmapDrawable) myDrawable).getBitmap();
createMultiPagePDF();
fabPDF.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (boolean_save) {
Intent intent = new Intent(getApplicationContext(), PDFViewActivity.class);
intent.putExtra("pdfFile", targetPdf);
startActivity(intent);
} else {
if (boolean_permission) {
progressDialog = new ProgressDialog(DisplayPreview.this);
progressDialog.setMessage("Please wait");
// bitmap = loadBitmapFromView(imagesLV, imagesLV.getWidth(), imagesLV.getHeight());
bitmap = loadBitmapFromView(imagesLV, imagesLV.getWidth(), imagesLV.getHeight());
// makePDF();
createMultiplePDF();
} else {
}
createMultiplePDF();
// makePDF();
}
}
});
}
private void createMultiPagePDF() {
pDialog = new ProgressDialog(DisplayPreview.this);
pDialog.setMessage("Please wait...Creating Invitation");
pDialog.setCancelable(false);
pDialog.show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// This method will be executed once the timer is over
// Start your app main activity
if (boolean_save) {
Intent intent = new Intent(getApplicationContext(), PDFViewActivity.class);
intent.putExtra("pdfFile", targetPdf);
startActivity(intent);
} else {
if (boolean_permission) {
progressDialog = new ProgressDialog(DisplayPreview.this);
progressDialog.setMessage("Please wait");
// bitmap = loadBitmapFromView(imagesLV, imagesLV.getWidth(), imagesLV.getHeight());
bitmap = loadBitmapFromView(imagesLV, imagesLV.getWidth(), imagesLV.getHeight());
// makePDF();
createMultiplePDF();
} else {
}
createMultiplePDF();
// makePDF();
}
}
}, 4000);
}
public static Bitmap loadBitmapFromView(View v, int width, int height) {
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSIONS) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
boolean_permission = true;
} else {
Toast.makeText(getApplicationContext(), "Please allow the permission", Toast.LENGTH_LONG).show();
}
}
}
public void createMultiplePDF() {
// targetPdf = "mnt/sdcard/testing_1.pdf";
targetPdf = "mnt/sdcard/" + userNameStr + ".pdf";
File filePath = new File(targetPdf);
// Document document = new Document();
Document document = new Document(PageSize.A4, 0, 0, 0, 0);
// step 2
PdfWriter writer = null;
try {
writer = PdfWriter.getInstance(document, new FileOutputStream(filePath));
} catch (DocumentException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// step 3
document.open();
// step 4
try {
Drawable myDrawable = null;
for (int i = 0; i < selectedImagesList.size(); i++) {
//
String imagePath = selectedImagesList.get(i).replaceAll("^\"|\"$", "");
Log.i(TAG, "Image Path is :: 271 :: " + imagePath);
// if (imagePath.equals("R.drawable.img_8")) {
if (imagePath.equals(userNameStr)) {
Bitmap processedBitmap = ProcessingBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
processedBitmap.compress(Bitmap.CompressFormat.JPEG, 40, stream);
Image myImg = Image.getInstance(stream.toByteArray());
DisplayMetrics displaymetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
float hight = (float) ((displaymetrics.heightPixels / 2) * (1.1));
float width = (float) ((displaymetrics.widthPixels / 2) * (1.6));
// myImg.scaleToFit(hight, width);
myImg.scaleToFit(PageSize.ARCH_A);
myImg.setAlignment(Image.ALIGN_CENTER);
document.add(myImg);
writer.setPageEmpty(false);
}
if (imagePath.equals("R.drawable.img_2")) {
myDrawable = getResources().getDrawable(R.drawable.img_2);
Bitmap myLogo = ((BitmapDrawable) myDrawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
myLogo.compress(Bitmap.CompressFormat.JPEG, 40, stream);
Image myImg = Image.getInstance(stream.toByteArray());
DisplayMetrics displaymetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
float hight = (float) ((displaymetrics.heightPixels / 2) * (1.1));
float width = (float) ((displaymetrics.widthPixels / 2) * (1.6));
// myImg.scaleToFit(hight, width);
myImg.scaleToFit(PageSize.ARCH_A);
myImg.setAlignment(Image.ALIGN_CENTER);
document.add(myImg);
writer.setPageEmpty(false);
}
if (imagePath.equals("R.drawable.img_3")) {
myDrawable = getResources().getDrawable(R.drawable.img_3);
Bitmap myLogo = ((BitmapDrawable) myDrawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
myLogo.compress(Bitmap.CompressFormat.JPEG, 40, stream);
Image myImg = Image.getInstance(stream.toByteArray());
DisplayMetrics displaymetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
float hight = (float) ((displaymetrics.heightPixels / 2) * (1.1));
float width = (float) ((displaymetrics.widthPixels / 2) * (1.6));
// myImg.scaleToFit(hight, width);
myImg.scaleToFit(PageSize.ARCH_A);
myImg.setAlignment(Image.ALIGN_CENTER);
document.add(myImg);
writer.setPageEmpty(false);
}
if (imagePath.equals("R.drawable.img_4")) {
myDrawable = getResources().getDrawable(R.drawable.img_4);
Bitmap myLogo = ((BitmapDrawable) myDrawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
myLogo.compress(Bitmap.CompressFormat.JPEG, 40, stream);
Image myImg = Image.getInstance(stream.toByteArray());
DisplayMetrics displaymetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
float hight = (float) ((displaymetrics.heightPixels / 2) * (1.1));
float width = (float) ((displaymetrics.widthPixels / 2) * (1.6));
// myImg.scaleToFit(hight, width);
myImg.scaleToFit(PageSize.ARCH_A);
myImg.setAlignment(Image.ALIGN_CENTER);
document.add(myImg);
writer.setPageEmpty(false);
}
if (imagePath.equals("R.drawable.img_5")) {
myDrawable = getResources().getDrawable(R.drawable.img_5);
Bitmap myLogo = ((BitmapDrawable) myDrawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
myLogo.compress(Bitmap.CompressFormat.JPEG, 40, stream);
Image myImg = Image.getInstance(stream.toByteArray());
DisplayMetrics displaymetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
float hight = (float) ((displaymetrics.heightPixels / 2) * (1.1));
float width = (float) ((displaymetrics.widthPixels / 2) * (1.6));
// myImg.scaleToFit(hight, width);
myImg.scaleToFit(PageSize.ARCH_A);
myImg.setAlignment(Image.ALIGN_CENTER);
document.add(myImg);
writer.setPageEmpty(false);
}
if (imagePath.equals("R.drawable.img_6")) {
myDrawable = getResources().getDrawable(R.drawable.img_6);
Bitmap myLogo = ((BitmapDrawable) myDrawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
myLogo.compress(Bitmap.CompressFormat.JPEG, 40, stream);
Image myImg = Image.getInstance(stream.toByteArray());
DisplayMetrics displaymetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
float hight = (float) ((displaymetrics.heightPixels / 2) * (1.1));
float width = (float) ((displaymetrics.widthPixels / 2) * (1.6));
// myImg.scaleToFit(hight, width);
myImg.scaleToFit(PageSize.ARCH_A);
myImg.setAlignment(Image.ALIGN_CENTER);
document.add(myImg);
writer.setPageEmpty(false);
}
if (imagePath.equals("R.drawable.img_7")) {
myDrawable = getResources().getDrawable(R.drawable.img_7);
Bitmap myLogo = ((BitmapDrawable) myDrawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
myLogo.compress(Bitmap.CompressFormat.JPEG, 40, stream);
Image myImg = Image.getInstance(stream.toByteArray());
DisplayMetrics displaymetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
float hight = (float) ((displaymetrics.heightPixels / 2) * (1.1));
float width = (float) ((displaymetrics.widthPixels / 2) * (1.6));
// myImg.scaleToFit(hight, width);
myImg.scaleToFit(PageSize.ARCH_A);
myImg.setAlignment(Image.ALIGN_CENTER);
document.add(myImg);
writer.setPageEmpty(false);
}
/* if (imagePath.equals("R.drawable.img_8")) {
myDrawable = getResources().getDrawable(R.drawable.img_8);
Bitmap myLogo = ((BitmapDrawable) myDrawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
myLogo.compress(Bitmap.CompressFormat.JPEG, 40, stream);
Image myImg = Image.getInstance(stream.toByteArray());
DisplayMetrics displaymetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
float hight = (float) ((displaymetrics.heightPixels / 2) * (1.1));
float width = (float) ((displaymetrics.widthPixels / 2) * (1.6));
// myImg.scaleToFit(hight, width);
myImg.scaleToFit(PageSize.ARCH_A);
myImg.setAlignment(Image.ALIGN_CENTER);
document.add(myImg);
writer.setPageEmpty(false);
} if (imagePath.equals("R.drawable.img_9")) {
myDrawable = getResources().getDrawable(R.drawable.img_9);
Bitmap myLogo = ((BitmapDrawable) myDrawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
myLogo.compress(Bitmap.CompressFormat.JPEG, 40, stream);
Image myImg = Image.getInstance(stream.toByteArray());
DisplayMetrics displaymetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
float hight = (float) ((displaymetrics.heightPixels / 2) * (1.1));
float width = (float) ((displaymetrics.widthPixels / 2) * (1.6));
// myImg.scaleToFit(hight, width);
myImg.scaleToFit(PageSize.ARCH_A);
myImg.setAlignment(Image.ALIGN_CENTER);
document.add(myImg);
writer.setPageEmpty(false);
}*/
}
document.close();
pDialog.dismiss();
Intent intent = new Intent(getApplicationContext(), PDFViewActivity.class);
intent.putExtra("pdfFile", targetPdf);
startActivity(intent);
finish();
} catch (DocumentException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
#SuppressLint("ResourceAsColor")
private Bitmap ProcessingBitmap() {
Resources resources = DisplayPreview.this.getResources();
float scale = resources.getDisplayMetrics().density;
Bitmap bm1 = BitmapFactory.decodeResource(getResources(), R.drawable.img_1);
Bitmap.Config config = bm1.getConfig();
if (config == null) {
config = Bitmap.Config.ARGB_8888;
}
// newBitmap = Bitmap.createBitmap(bm1.getWidth(), bm1.getHeight(), config);
anImage = Bitmap.createBitmap(bm1.getWidth(), bm1.getHeight(), config);
// Canvas newCanvas = new Canvas(newBitmap);
Canvas newCanvas = new Canvas(anImage);
newCanvas.drawBitmap(bm1, 0, 0, null);
String captionString = userNameStr.trim();
if (captionString != null) {
TextPaint paintText = new TextPaint(Paint.ANTI_ALIAS_FLAG);
paintText.setColor(R.color.wedding_guest_name);
paintText.setTextSize(100);
paintText.setStyle(Paint.Style.FILL_AND_STROKE);
paintText.setTextAlign(Paint.Align.CENTER);
int textWidth = newCanvas.getWidth() - (int) (250 * scale);
StaticLayout textLayout = new StaticLayout(
captionString, paintText, textWidth, Layout.Alignment.ALIGN_LEFT, 1.0f, 1.4f, false);
Rect rectText = new Rect();
paintText.getTextBounds(captionString, 0, captionString.length(), rectText);
float xPos = (newCanvas.getWidth() / 2.16f);
float yPos = (int) ((newCanvas.getHeight() / 2.4) - ((paintText.descent() + paintText.ascent()) / 3.0));
float x = newCanvas.getWidth()/2;
// float y = newCanvas.getHeight()/2;
// draw text to the Canvas center
newCanvas.save();
// newCanvas.translate(xPos, yPos);
newCanvas.translate(x, yPos);
textLayout.draw(newCanvas);
newCanvas.restore();
// drawMultiLineText(captionString,xPos, yPos, paintText, newCanvas);
// newCanvas.drawText(captionString,xPos, yPos, paintText);
} else {
Toast.makeText(getApplicationContext(),
"caption empty!",
Toast.LENGTH_LONG).show();
}
// return newBitmap;
return anImage;
}
}
I suggest you to use iTextPdf to create pdf in easy way
compile 'com.itextpdf:itextg:5.5.10'
Add itextpdf library into your project app build.gradle file
implementation 'com.itextpdf:itext-pdfa:5.5.5'
Below is the code to create pdf file and add image into each cell in table
Document document = new Document(PageSize.A4, 10, 10, 10, 10);
try {
File f = new File(Environment.getExternalStorageDirectory() + "/*foldername*");
f = new File(f.getAbsolutePath() + "/" + * filename *);
if (!f.exists()) {
f.mkdir();
}
PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(f.getAbsolutePath() + "/" + * filename * +".pdf"));
document.open();
for (int l = 0; l < list.size; l++) {
PdfPTable thirdPart = new PdfPTable(col);
thirdPart.getDefaultCell().setBorder(Rectangle.NO_BORDER);
thirdPart.setWidthPercentage(100.0f);
thirdPart.setHorizontalAlignment(Element.ALIGN_LEFT);
Image str = list.get(l);
PdfPCell imageCell = new PdfPCell(str);
thirdPart.addCell(imageCell);
}
document.add(thirdPart);
} catch (Exception e) {
e.printStackTrace();
}
document.close();
I'm writing a small Android program in Android Studio that uses MediaProjection to grab a screenshot of the whole screen and then I want to pass that screenshot as a Bitmap to my System Overlay (based on the chatheads example). When the MediaProjection runs and the Imagereader creates the bitmaps, I'm passing the bitmap into a class global variable so I can pass it into my System Overlay service and display it. I'm running into an issue where when the Imageview inside the service tries to read the bmp, I get an error as follows:
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap#347a4d5
From my understanding, the garbage collector quickly eats up the passed Bitmap and when the System Overlay tries to grab it, the data is gone. Could someone point me in the right direction on how to keep the bitmap?
Main Activity
package com.example.chatheads;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.media.ImageReader;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.Image;
import android.media.ImageReader;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.OrientationEventListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
public class MainActivity extends Activity {
Button startService,stopService;
private static final String TAG = MainActivity.class.getName();
private static final int REQUEST_CODE = 100;
private static String STORE_DIRECTORY;
private static int IMAGES_PRODUCED;
private static final String SCREENCAP_NAME = "screencap";
private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
private static MediaProjection sMediaProjection;
private MediaProjectionManager mProjectionManager;
private ImageReader mImageReader;
private Handler mHandler;
private Display mDisplay;
private VirtualDisplay mVirtualDisplay;
private int mDensity;
private int mWidth;
private int mHeight;
private int mRotation;
private OrientationChangeCallback mOrientationChangeCallback;
private Image image = null;
private Bitmap bitmap = null;
Globals sharedData = Globals.getInstance();
public Bitmap getObjectContainer() {
return bitmap;
}
private class ImageAvailableListener implements ImageReader.OnImageAvailableListener {
#Override
public void onImageAvailable(ImageReader reader) {
FileOutputStream fos = null;
try {
image = mImageReader.acquireLatestImage();
if (image != null) {
Image.Plane[] planes = image.getPlanes();
ByteBuffer buffer = planes[0].getBuffer();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * mWidth;
// create bitmap
bitmap = Bitmap.createBitmap(mWidth + rowPadding / pixelStride, mHeight, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
sharedData.setScreenshot(bitmap);
// write bitmap to a file
// fos = new FileOutputStream(STORE_DIRECTORY + "/myscreen_" + IMAGES_PRODUCED + ".png");
//bitmap.compress(CompressFormat.JPEG, 100, fos);
IMAGES_PRODUCED++;
//Log.e(TAG, "captured image: " + IMAGES_PRODUCED);
String s = ("captured image: " + String.valueOf(IMAGES_PRODUCED));
Toast toast1 = Toast.makeText(getBaseContext(),s, Toast.LENGTH_SHORT);
toast1.show();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos!=null) {
try {
fos.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
if (bitmap!=null) {
bitmap.recycle();
}
if (image!=null) {
image.close();
}
}
}
}
private class OrientationChangeCallback extends OrientationEventListener {
public OrientationChangeCallback(Context context) {
super(context);
}
#Override
public void onOrientationChanged(int orientation) {
synchronized (this) {
final int rotation = mDisplay.getRotation();
if (rotation != mRotation) {
mRotation = rotation;
try {
// clean up
if(mVirtualDisplay != null) mVirtualDisplay.release();
if(mImageReader != null) mImageReader.setOnImageAvailableListener(null, null);
// re-create virtual display depending on device width / height
createVirtualDisplay();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
private class MediaProjectionStopCallback extends MediaProjection.Callback {
#Override
public void onStop() {
Log.e("ScreenCapture", "stopping projection.");
mHandler.post(new Runnable() {
#Override
public void run() {
if(mVirtualDisplay != null) mVirtualDisplay.release();
if(mImageReader != null) mImageReader.setOnImageAvailableListener(null, null);
if(mOrientationChangeCallback != null) mOrientationChangeCallback.disable();
sMediaProjection.unregisterCallback(MediaProjectionStopCallback.this);
}
});
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sharedData.setValue(1);
// call for the projection manager
mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
// start projection
Button startButton = (Button)findViewById(R.id.startButton);
startButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
startProjection();
}
});
// stop projection
Button stopButton = (Button)findViewById(R.id.stopButton);
stopButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
stopProjection();
}
});
// start capture handling thread
new Thread() {
#Override
public void run() {
Looper.prepare();
mHandler = new Handler();
Looper.loop();
}
}.start();
startService=(Button)findViewById(R.id.startService);
stopService=(Button)findViewById(R.id.stopService);
startService.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
startService(new Intent(getApplication(), ChatHeadService.class));
}
});
stopService.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
stopService(new Intent(getApplication(), ChatHeadService.class));
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
sMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
if (sMediaProjection != null) {
File externalFilesDir = getExternalFilesDir(null);
if (externalFilesDir != null) {
STORE_DIRECTORY = externalFilesDir.getAbsolutePath() + "/screenshots/";
File storeDirectory = new File(STORE_DIRECTORY);
if (!storeDirectory.exists()) {
boolean success = storeDirectory.mkdirs();
if (!success) {
Log.e(TAG, "failed to create file storage directory.");
return;
}
}
} else {
Log.e(TAG, "failed to create file storage directory, getExternalFilesDir is null.");
return;
}
// display metrics
DisplayMetrics metrics = getResources().getDisplayMetrics();
mDensity = metrics.densityDpi;
mDisplay = getWindowManager().getDefaultDisplay();
// create virtual display depending on device width / height
createVirtualDisplay();
// register orientation change callback
mOrientationChangeCallback = new OrientationChangeCallback(this);
if (mOrientationChangeCallback.canDetectOrientation()) {
mOrientationChangeCallback.enable();
}
// register media projection stop callback
sMediaProjection.registerCallback(new MediaProjectionStopCallback(), mHandler);
}
}
}
/****************************************** UI Widget Callbacks *******************************/
private void startProjection() {
startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
}
private void stopProjection() {
mHandler.post(new Runnable() {
#Override
public void run() {
if (sMediaProjection != null) {
sMediaProjection.stop();
}
}
});
}
/****************************************** Factoring Virtual Display creation ****************/
private void createVirtualDisplay() {
// get width and height
Point size = new Point();
mDisplay.getSize(size);
mWidth = size.x;
mHeight = size.y;
// start capture reader
mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat.RGBA_8888, 2);
mVirtualDisplay = sMediaProjection.createVirtualDisplay(SCREENCAP_NAME, mWidth, mHeight, mDensity, VIRTUAL_DISPLAY_FLAGS, mImageReader.getSurface(), null, mHandler);
mImageReader.setOnImageAvailableListener(new ImageAvailableListener(), mHandler);
}
}
Service
package com.example.chatheads;
import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.content.Context;
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.graphics.Paint.Style;
import android.view.View;
import android.widget.Toast;
public class ChatHeadService extends Service {
private WindowManager windowManager;
private ImageView chatHead;
WindowManager.LayoutParams params;
Globals sharedData = Globals.getInstance();
#Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
DisplayMetrics displayMetrics = new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
int h = displayMetrics.heightPixels, w = displayMetrics.widthPixels;
Bitmap.Config conf = Bitmap.Config.ARGB_8888; // see other conf types
final Bitmap bmp = Bitmap.createBitmap(w, h, conf); // this creates a MUTABLE bitmap
Canvas canvas = new Canvas(bmp);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStrokeWidth(5);
paint.setAlpha(60);
Rect rect=new Rect(0, 0, bmp.getWidth(), bmp.getHeight());
canvas.drawRect(rect,paint);
paint.setColor(Color.GREEN);
canvas.drawLine(0, 0, 0, h, paint);
canvas.drawLine(0, 0, w, 0, paint);
canvas.drawLine(w, 0, h, w, paint);
canvas.drawLine(0, 0, 0, w, paint);
chatHead = new ImageView(this);
chatHead.setImageResource(R.drawable.face1);
params= new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 1000;
//this code is for dragging the chat head
chatHead.setOnTouchListener(new View.OnTouchListener() {
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
boolean isExpanded = false;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = params.x;
initialY = params.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
int n = sharedData.getValue();
//Toast toast1 = Toast.makeText(getBaseContext(),String.valueOf(n), Toast.LENGTH_SHORT);
//toast1.show();
if (isExpanded == true){
chatHead.setImageResource(R.drawable.face1);
isExpanded=false;
params.x = 0;
params.y = 1000;
windowManager.updateViewLayout(chatHead, params);
}
else{
//chatHead.setImageResource(R.drawable.clear);
Bitmap bmp2 = sharedData.getScreenshot();
chatHead.setImageBitmap(bmp2);
isExpanded = true;
params.x = 0;
params.y = 0;
windowManager.updateViewLayout(chatHead, params);
}
return true;
case MotionEvent.ACTION_UP:
//chatHead.setImageResource(R.drawable.test);
return true;
/*case MotionEvent.ACTION_MOVE:
params.x = initialX
+ (int) (event.getRawX() - initialTouchX);
params.y = initialY
+ (int) (event.getRawY() - initialTouchY);
windowManager.updateViewLayout(chatHead, params);
return true;*/
}
return false;
}
});
windowManager.addView(chatHead, params);
}
#Override
public void onDestroy() {
super.onDestroy();
if (chatHead != null)
windowManager.removeView(chatHead);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Globals
package com.example.chatheads;
import android.graphics.Bitmap;
public class Globals {
private static Globals instance = new Globals();
// Getter-Setters
public static Globals getInstance() {
return instance;
}
public static void setInstance(Globals instance) {
Globals.instance = instance;
}
private Globals() {
}
private int testi;
private Bitmap bmpscreenshot;
public Bitmap getScreenshot(){
return bmpscreenshot;
}
public void setScreenshot(Bitmap bmp){
this.bmpscreenshot = bmp;
}
public int getValue() {
return testi;
}
public void setValue(int testi) {
this.testi = testi;
}
}
You seem to be calling bitmap.recycle() too soon. Call it after the service has actually processed the data.
If you want a pass a Bitmap from Activity to service means, convert the bitmap into ByteArray
Intent i = new Intent(this, YourService.class);
Bitmap b; // your bitmap
ByteArrayOutputStream bs = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.PNG, 50, bs);
i.putExtra("byteArray", bs.toByteArray());
startService(i);
Override onStartCommand in your service
public int onStartCommand (Intent intent, int flags, int startId) {
Bitmap b = BitmapFactory.decodeByteArray(
getIntent().getByteArrayExtra("byteArray"),0,getIntent()
.getByteArrayExtra("byteArray").length);
return null;
}
I want to take a picture using the camera and compress it and store it in the path I created.
What I have done right now is clicking the picture and store the original picture in my path but I want to compress it before storing it so I can retrieve the path of the compressed image.
To save the original image I have created my own path and it is stored in the variable mCurrentPhotoPath.
The main thing is I want the path it is stored.
Please help. Thanks in advance.
package com.howaboutthis.satyaraj.videntify;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.firebase.auth.FirebaseAuth;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.Date;
public class IdentifyActivity extends AppCompatActivity implements View.OnClickListener {
private static final int PICK_IMAGE_REQUEST = 1;
private static final int REQUEST_TAKE_PHOTO = 200;
private static final int CLICK_IMAGE_REQUEST = 2;
private static final String TAG = "IdentifyActivity";
private RequestPermissionHandler mRequestPermissionHandler;
String mCurrentPhotoPath;
String userName;
String userEmail;
Uri profileURL;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_identify);
mRequestPermissionHandler = new RequestPermissionHandler();
Bundle bundle = getIntent().getExtras();
assert bundle != null;
userName = bundle.getString("username");
Button cameraButton = findViewById(R.id.camera);
Button galleryButton = findViewById(R.id.gallery);
cameraButton.setOnClickListener(this);
galleryButton.setOnClickListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_profile) {
Intent intent = new Intent(IdentifyActivity.this, ProfileActivity.class);
intent.putExtra("username", userName);
intent.putExtra("user_email", userEmail);
intent.putExtra("profile_url",profileURL);
startActivity(intent);
}
else if (id == R.id.action_about)
return true;
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.camera:
takePicture();
break;
case R.id.gallery:
pickFromGallery();
break;
}
}
private void pickFromGallery() {
String[] PERMISSIONS = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
mRequestPermissionHandler.requestPermission(this, PERMISSIONS, REQUEST_TAKE_PHOTO, new RequestPermissionHandler.RequestPermissionListener() {
#Override
public void onSuccess() {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(intent, PICK_IMAGE_REQUEST);
}
#Override
public void onFailed() {
Toast.makeText(IdentifyActivity.this, "Request permission failed", Toast.LENGTH_SHORT).show();
}
});
}
private void takePicture() {
String[] PERMISSIONS = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE};
mRequestPermissionHandler.requestPermission(this, PERMISSIONS, REQUEST_TAKE_PHOTO, new RequestPermissionHandler.RequestPermissionListener() {
#Override
public void onSuccess() {
dispatchTakePictureIntent();
}
#Override
public void onFailed() {
Toast.makeText(IdentifyActivity.this, "Request permission failed", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onBackPressed() {
super.onBackPressed();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
System.exit(0);
}
#Override
protected void onDestroy() {
super.onDestroy();
finish();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri uri = data.getData();
File finalFile = new File(getRealPathFromURI(uri));
Intent intent = new Intent(IdentifyActivity.this, detailedActivity.class);
intent.putExtra("PATH", finalFile.getPath());
startActivity(intent);
} else if (requestCode == CLICK_IMAGE_REQUEST && resultCode == RESULT_OK) {
galleryAddPic();
Intent intent = new Intent(IdentifyActivity.this, detailedActivity.class);
intent.putExtra("PATH", mCurrentPhotoPath);
startActivity(intent);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
mRequestPermissionHandler.onRequestPermissionsResult(requestCode, permissions,
grantResults);
}
public String getRealPathFromURI(Uri uri) {
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(uri, filePathColumn, null, null, null);
String picturePath = null;
if (cursor != null) {
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
picturePath = cursor.getString(columnIndex);
cursor.close();
}
return picturePath;
}
//Creating a path for the captured image to be saved. Using this path we can retrieve the original Image.
private File createImageFile() throws IOException {
// Create an image file name
#SuppressLint("SimpleDateFormat") String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
Log.e(TAG,"Error while creating the file");
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.howaboutthis.satyaraj.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, CLICK_IMAGE_REQUEST);
}
}
}
// Adding the pic to the gallery so that it is visible to everyone
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
}
Simply read load and save it
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inSampleSize = 2; //you can also calculate your inSampleSize
options.inJustDecodeBounds = false;
options.inTempStorage = new byte[16 * 1024];
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bmp= BitmapFactory.decodeFile(photoPath, options);
FileOutputStream out = null;
try {
out = new FileOutputStream(photoPath);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
// PNG is a lossless format, the compression factor (100) is ignored
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
If you want a really small image then you also have to change it's resolution
public String compressImage(String imagePath) {
Bitmap scaledBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(imagePath, options);
int actualHeight = options.outHeight;
int actualWidth = options.outWidth;
float imgRatio = (float) actualWidth / (float) actualHeight;
float maxRatio = maxWidth / maxHeight;
if (actualHeight > maxHeight || actualWidth > maxWidth) {
if (imgRatio < maxRatio) {
imgRatio = maxHeight / actualHeight;
actualWidth = (int) (imgRatio * actualWidth);
actualHeight = (int) maxHeight;
} else if (imgRatio > maxRatio) {
imgRatio = maxWidth / actualWidth;
actualHeight = (int) (imgRatio * actualHeight);
actualWidth = (int) maxWidth;
} else {
actualHeight = (int) maxHeight;
actualWidth = (int) maxWidth;
}
}
options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
try {
bmp = BitmapFactory.decodeFile(imagePath, options);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
try {
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.RGB_565);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
float ratioX = actualWidth / (float) options.outWidth;
float ratioY = actualHeight / (float) options.outHeight;
float middleX = actualWidth / 2.0f;
float middleY = actualHeight / 2.0f;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
if(bmp!=null)
{
bmp.recycle();
}
ExifInterface exif;
try {
exif = new ExifInterface(imagePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
} else if (orientation == 3) {
matrix.postRotate(180);
} else if (orientation == 8) {
matrix.postRotate(270);
}
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
} catch (IOException e) {
e.printStackTrace();
}
FileOutputStream out = null;
String filepath = getFilename();
try {
out = new FileOutputStream(filepath);
//write the compressed bitmap at the destination specified by filename.
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return filepath;
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
final float totalPixels = width * height;
final float totalReqPixelsCap = reqWidth * reqHeight * 2;
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++;
}
return inSampleSize;
}
I'm working in an app that take an image from the gallery and save it into parse.
The problem is that when I pick an image taken by the camera the size of the image is too big and takes some seconds to load the image in an image view. Also when I save the image and download again in the app it takes a lot of time because it has to download a big image.
I don't know how I reduce the size of the image picked. I tried several things but anything works.
This is my code at this moment
public class Datos extends Activity implements OnItemSelectedListener {
private final int SELECT_PHOTO = 1;
private ImageButton imageView;
ParseFile file;
byte [] data;
/*
public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
int width = bm.getWidth();
int height = bm.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(
bm, 0, 0, width, height, matrix, false);
bm.recycle();
return resizedBitmap;
}
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_datos);
btnClick();
imageView = (ImageButton) findViewById(R.id.imageButton);
ImageButton pickImage = (ImageButton) findViewById(R.id.imageButton);
pickImage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
//photoPickerIntent.putExtra("outputX", 150);
//photoPickerIntent.putExtra("outputY", 100);
//photoPickerIntent.putExtra("aspectX", 1);
//photoPickerIntent.putExtra("aspectY", 1);
//photoPickerIntent.putExtra("scale", true);
startActivityForResult(photoPickerIntent, SELECT_PHOTO);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch (requestCode) {
case SELECT_PHOTO:
if (resultCode == RESULT_OK) {
try {
Uri imageUri = imageReturnedIntent.getData();
InputStream imageStream = getContentResolver().openInputStream(imageUri);
Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
imageView.setImageBitmap(selectedImage);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
selectedImage.compress(Bitmap.CompressFormat.PNG, 100, stream);
data = stream.toByteArray();
BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), selectedImage);
imageView.setBackgroundDrawable(bitmapDrawable);
BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
Bitmap bmp = drawable.getBitmap();
Bitmap b = Bitmap.createScaledBitmap(bmp, 120, 120, false);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
}
#Override
public void onItemSelected(AdapterView<?> parent, View v, int position,
long id) {
// TODO Auto-generated method stub
Spinner spinner = (Spinner) parent;
if (spinner.getId() == R.id.telefono) {
consola = parent.getItemAtPosition(position).toString();
} else if (spinner.getId() == R.id.provincia) {
provincia = parent.getItemAtPosition(position).toString();
}
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
public void btnClick() {
Button buttonEnviar = (Button) findViewById(R.id.enviar);
buttonEnviar.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
//Storing image in parse passed in onclick method of a button with the below code:
Intent intentDatos = new Intent(Datos.this, Inicio.class);
startActivity(intentDatos);
ParseObject testObject = new ParseObject("Musica");
if (data != null) {
file = new ParseFile("selected.png", data);
}
else {
data = "".getBytes();
file = new ParseFile("selected.png", data);
}
//file.saveInBackground();
testObject.put("imagen", file);
testObject.saveInBackground();
}
});
}
Does Anyone know how to do it?
Thanks for your help,
This answer will help you
if you want bitmap ratio same and reduce bitmap size. then pass your
maximum size bitmap. you can use this function
public Bitmap getResizedBitmap(Bitmap image, int maxSize) {
int width = image.getWidth();
int height = image.getHeight();
float bitmapRatio = (float)width / (float) height;
if (bitmapRatio > 1) {
width = maxSize;
height = (int) (width / bitmapRatio);
} else {
height = maxSize;
width = (int) (height * bitmapRatio);
}
return Bitmap.createScaledBitmap(image, width, height, true);
}
change your onActivityResult in SELECT_PHOTO case like this:
case SELECT_PHOTO:
if (resultCode == RESULT_OK) {
try {
Uri imageUri = imageReturnedIntent.getData();
InputStream imageStream = getContentResolver().openInputStream(imageUri);
Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
selectedImage = getResizedBitmap(selectedImage, 400);// 400 is for example, replace with desired size
imageView.setImageBitmap(selectedImage);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
The first file allow the user to pick a photo from the gallery and sends it to an activity which will process it. The problem is that the image is too large for the phone's screen, so you only see the top corner of the image(as if it has been magnified).
Button useGallery = (Button)findViewById(R.id.loadfromgallery);
useGallery.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);
}}) ;
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case SELECT_PHOTO:
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.getData();
InputStream imageStream = null;
try {
imageStream = getContentResolver().openInputStream(selectedImage);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream);
Intent intent = new Intent(mContext, DisplayUndistortedBitmapFromGalleryActivity.class);
intent.setData(selectedImage);
startActivity(intent);
if(yourSelectedImage != null){
Log.e(TAG,"pic ok");
}else{
Log.e(TAG,"pic not ok");
}
}
}
. The 2nd file is the activity that recieves the image data from the intent and places it in a URI that a bitmap is the derived from.
public class DisplayUndistortedBitmapFromGalleryActivity extends Activity {
private static final String TAG = "*********DUBFGActivity";
private Context mContext = this;
Uri uri;
private Bitmap mbitmap = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
uri = getIntent().getData();
if(uri != null){
Log.e(TAG, "uri ok");
}else {
Log.e(TAG, "uri not ok");
}
try {
mbitmap = Media.getBitmap(getContentResolver(), uri);
//setMbitmap(bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
.
I have a 3rd file which is the customview for the activity. The line below retrieves the bitmap from it's activity and displays it. Is there a way of downsizing the bitmap so it fits on the screen? thanks.
Bitmap bm = ((DisplayUndistortedBitmapFromGalleryActivity)getContext()).getMbitmap();
Here is how i usually resize a bitmap and is the easiest way.
public class bitmaptest extends Activity {
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
LinearLayout linLayout = new LinearLayout(this);
// load the origial BitMap (500 x 500 px)
Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),
R.drawable.android);
int width = bitmapOrg.width();
int height = bitmapOrg.height();
int newWidth = 200;
int newHeight = 200;
// calculate the scale - in this case = 0.4f
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// createa matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// rotate the Bitmap
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,
width, height, matrix, true);
// make a Drawable from Bitmap to allow to set the BitMap
// to the ImageView, ImageButton or what ever
BitmapDrawable bmd = new BitmapDrawable
EDIT:
Here is another option.
int targetWidth = bitmapOrg.getWidth() - 15; //change this to control the size
int targetHeight = bitmapOrg.getHeight() - 15 ;
Matrix matrix = new Matrix();
matrix.postScale(1f, 1f);
Bitmap resizedBitmap = Bitmap.createBitmap(bmp, 0, 0, targetWidth, targetHeight, matrix, true);