UPDATES: Even if i don't retrieve images from cache, i tried to retrieve via Drawable where i stored all the 18 images in the "drawable-mdpi" folder. Still, a blank screen was display.
I was able to retrieved images from the server and save the image (.GIF) into the cache. However, when i need to load that image from cache, the image doesn't show up on screen. Here is the codes that does the work:
File cacheDir = context.getCacheDir();
File cacheMap = new File(cacheDir, smallMapImageNames.get(i).toString());
if(cacheMap.exists()){
FileInputStream fis = null;
try {
fis = new FileInputStream(cacheMap);
Bitmap local = BitmapFactory.decodeStream(fis);
puzzle.add(local);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}else{
Drawable smallMap = LoadImageFromWebOperations(mapPiecesURL.get(i).toString());
if(i==0){
height1 = smallMap.getIntrinsicHeight();
width1 = smallMap.getIntrinsicWidth();
}
if (smallMap instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable)smallMap).getBitmap();
FileOutputStream fos = null;
try {
cacheMap.createNewFile();
fos = new FileOutputStream(cacheMap);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
puzzle.add(bitmap);
}
}
ArrayList to store the image names: smallMapImageNames (The image names can also be found in the URL)
ArrayList to store the URL of the images: mapPiecesURL
To sum it up i have 2 questions
1) how to load images from cache?
2) regarding the bitmap.compress(), the images from the server is .GIF format but i apply Bitmap.CompressFormat.PNG. So is there going to be any problem with this?
Can anyone please help me with this?
The two functions
private Bitmap getBitMap(Context context) {
// TODO Auto-generated method stub
WifiPositioningServices wifiPositioningServices = new WifiPositioningServices();
String[] mapURLandCalibratedPoint1 = wifiPositioningServices.GetMapURLandCalibratedPoint("ERLab-1_1.GIF","ERLab"); //list of map pieces url in the first 9 pieces
String[] mapURLandCalibratedPoint2 = wifiPositioningServices.GetMapURLandCalibratedPoint("ERLab-4_1.GIF","ERLab"); //list of map pieces url in the last 9 pieces
ArrayList<String> smallMapImageNames = new ArrayList<String>();
ArrayList<String> mapPiecesURL = new ArrayList<String>();
for(int i=0; i<mapURLandCalibratedPoint1.length; i++){
if(mapURLandCalibratedPoint1[i].length()>40){ //image url
int len = mapURLandCalibratedPoint1[i].length();
int subStrLen = len-13;
smallMapImageNames.add(mapURLandCalibratedPoint1[i].substring(subStrLen, len-3)+"JPEG");
mapPiecesURL.add(mapURLandCalibratedPoint1[i]);
}
else{
//perform other task
}
}
for(int i=0; i<mapURLandCalibratedPoint2.length; i++){
if(mapURLandCalibratedPoint2[i].length()>40){ //image url
int len = mapURLandCalibratedPoint2[i].length();
int subStrLen = len-13;
smallMapImageNames.add(mapURLandCalibratedPoint2[i].substring(subStrLen, len-3)+"JPEG");
mapPiecesURL.add(mapURLandCalibratedPoint2[i]);
}
else{
//perform other task
}
}
Bitmap result = Bitmap.createBitmap(1029, 617, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
ArrayList<Bitmap> puzzle = new ArrayList<Bitmap>();
int height1 = 0 ;
int width1 = 0;
File cacheDir = context.getCacheDir();
for(int i=0; i<18; i++){
File cacheMap = new File(cacheDir, smallMapImageNames.get(i).toString());
if(cacheMap.exists()){
//retrieved from cached
try {
FileInputStream fis = new FileInputStream(cacheMap);
Bitmap bitmap = BitmapFactory.decodeStream(fis);
puzzle.add(bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
//retrieve from server and cached it
Drawable smallMap = LoadImageFromWebOperations(mapPiecesURL.get(i).toString());
if(i==0){
height1 = smallMap.getIntrinsicHeight();
width1 = smallMap.getIntrinsicWidth();
}
if (smallMap instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable)smallMap).getBitmap();
FileOutputStream fos = null;
try {
cacheMap.createNewFile();
fos = new FileOutputStream(cacheMap);
bitmap.compress(CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
puzzle.add(bitmap);
}
}
}
Rect srcRect;
Rect dstRect;
int cnt =0;
for (int j = 0; j < 3; j++) {
int newHeight = height1 * (j % 3);
for (int k = 0; k < 3; k++) {
if (j == 0 && k == 0) {
srcRect = new Rect(0, 0, width1, height1);
dstRect = new Rect(srcRect);
} else {
int newWidth = width1 * k;
srcRect = new Rect(0, 0, width1, height1);
dstRect = new Rect(srcRect);
dstRect.offset(newWidth, newHeight);
}
canvas.drawBitmap(puzzle.get(cnt), srcRect, dstRect,null);
cnt++;
}
}
for(int a=0; a<3; a++){
int newHeight = height1 * (a % 3);
for (int k = 3; k < 6; k++) {
if (a == 0 && k == 0) {
srcRect = new Rect(0, 0, width1*3, height1);
dstRect = new Rect(srcRect);
} else {
int newWidth = width1 * k;
srcRect = new Rect(0, 0, width1, height1);
dstRect = new Rect(srcRect);
dstRect.offset(newWidth, newHeight);
}
canvas.drawBitmap(puzzle.get(cnt), srcRect, dstRect,
null);
cnt++;
}
}
return result;
}
private Drawable LoadImageFromWebOperations(String url) {
// TODO Auto-generated method stub
try
{
InputStream is = (InputStream) new URL(url).getContent();
Drawable d = Drawable.createFromStream(is, "src name");
return d;
}catch (Exception e) {
System.out.println("Exc="+e);
return null;
}
}
I am actually trying to display 18 pieces (3X6) of images to form up a floorplan. So to display the images, i use two for-loop to display it. the two .GIF images, ERLab-1_1.GIF and ERLab-4_1.GIF are the center piece of each group. For example, the first row of would be ERLab-0_0.GIF, ERLab-1_0.GIF, ERLab-2_0.GIF, ERLab-3_0.GIF, ERLab-4_0.GIF, ERLab-5_0.GIF. Second row would be XXX-X_1.GIF and XXX-X_2.GIF for the third row.
Lastly,
Bitmap resultMap = getBitMap(this.getContext());
bmLargeImage = Bitmap.createBitmap(1029 , 617, Bitmap.Config.ARGB_8888);
bmLargeImage = resultMap;
Then in the onDraw function would be drawing the image onto the canvas.
I just solved my own question.
In this line, canvas.drawBitmap(puzzle.get(cnt), srcRect, dstRect,null); within each of the for-loop which i am using it to draw the bitmap onto the canvas, i need to cast the each item in the ArrayList (puzzle) to Bitmap. Only then will the image get display.
I thought that if the ArrayList is definite as such, ArrayList<Bitmap> puzzle = new ArrayList<Bitmap>(); each items in the ArrayList would be of Bitmap type. But isn't that always true?
Related
I want to create multiple page pdf from Android listview. I have successfully achieved converting all the listview items into pdf even if they are not all visible using itextg. The problem I faced is that if the items in the listview or the captured image of the listview exceeds the length of the page in the pdf it cuts the the rest of the items.
I want to create a multiple page pdf if the first page is full then write the rest of the image part in the second image.
This is the code which creates the pdf by capturing all the listview item:
//method which generate pdf of the attendance data
private void save_as_pdf() {
//First Check if the external storage is writable
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)) {
// Toast.makeText(context,"")
}
//Create a directory for your PDF
final File pdfDir = new File(Environment.getExternalStorageDirectory() + "/Documents", "attendance_report");
if (!pdfDir.exists()) {
pdfDir.mkdir();
}
//take screen shoot of the entire listview of the attendance report
ListView listview = studentlist;
ListAdapter adapter = listview.getAdapter();
int itemscount = adapter.getCount();
int allitemsheight = 0;
List<Bitmap> bmps = new ArrayList<Bitmap>();
for (int i = 0; i < itemscount; i++) {
View childView = adapter.getView(i, null, listview);
childView.measure(
View.MeasureSpec.makeMeasureSpec(listview.getWidth(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
childView.layout(0, 0, childView.getMeasuredWidth(), childView.getMeasuredHeight());
childView.setDrawingCacheEnabled(true);
childView.buildDrawingCache();
bmps.add(childView.getDrawingCache());
allitemsheight += childView.getMeasuredHeight();
}
Bitmap bigbitmap = Bitmap.createBitmap(listview.getMeasuredWidth(), allitemsheight,
Bitmap.Config.ARGB_8888);
Canvas bigcanvas = new Canvas(bigbitmap);
bigcanvas.drawColor(getResources().getColor(R.color.white));
Paint paint = new Paint();
int iHeight = 0;
for (int i = 0; i < bmps.size(); i++) {
Bitmap bmp = bmps.get(i);
bigcanvas.drawBitmap(bmp, 0, iHeight, paint);
iHeight += bmp.getHeight();
bmp.recycle();
bmp = null;
}
//Now create the name of your PDF file that you will generate
File pdfFile = new File(pdfDir, "report_for( " + course + "," + semister + section + "," + date + ").pdf");
try {
com.itextpdf.text.Document document = new com.itextpdf.text.Document();
PdfWriter.getInstance(document, new FileOutputStream(pdfFile));
document.addTitle("Attendance Report Generated For course:" + course + " Semester:" + semister + " Section:" + section + " Date:" + date);
document.addHeader("Header", "Department Of Information Science");
document.addCreator("Department Of Information Science");
document.addCreationDate();
document.bottomMargin();
document.setPageCount(3);
document.open();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bigbitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
addImage(document, byteArray);
document.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private void addImage(com.itextpdf.text.Document document, byte[] byteArray) {
Image image = null;
try {
image = Image.getInstance(byteArray);
} catch (BadElementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// image.scaleAbsolute(150f, 150f);
try {
document.add(image);
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//take screen shot all records from listview
for (int i = 0; i < itemscount; i++) {
listview.setSelection(i);
View childView = adapter.getView(i, null, listview);
ViewGroup.LayoutParams lp = childView.getLayoutParams();
if (lp == null) {
lp = new ViewGroup.LayoutParams(-2,-2);
}
lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
childView.setLayoutParams(lp);
childView.measure(View.MeasureSpec.makeMeasureSpec(listview.getWidth(),
View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
childView.layout(0, 0, childView.getMeasuredWidth(),
childView.getMeasuredHeight());
childView.setDrawingCacheEnabled(true);
childView.buildDrawingCache();
bmps.add(childView.getDrawingCache());
allitemsheight += childView.getMeasuredHeight();
}
I have a custom listview and I want to make pdf from the whole listview. I refered many posts and implemented below code which converts my listview to pdf. But problem is its not containing the whole listview item. Only first few items are available in the pdf.
My function to convert listview to pdf is
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)) {
}
File pdfDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOCUMENTS), "MyProject");
if (!pdfDir.exists()){
pdfDir.mkdir();
}
Bitmap screen = getWholeListViewItemsToBitmap();
File pdfFile = new File(pdfDir, "myPdfFile_new.pdf");
try {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(pdfFile));
document.open();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
screen.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
addImage(document,byteArray);
document.close();
}
catch (Exception e){
e.printStackTrace();
}
}
});
addImage method
private static void addImage(Document document,byte[] byteArray)
{
Image image = null;
try
{
image = Image.getInstance(byteArray);
}
catch (BadElementException e)
{
e.printStackTrace();
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
try
{
document.add(image);
} catch (DocumentException e) {
e.printStackTrace();
}
}
method to get list items
public Bitmap getWholeListViewItemsToBitmap() {
ListView listview = StockReportActivity.category_list;
ListAdapter adapter = listview.getAdapter();
int itemscount = adapter.getCount();
int allitemsheight = 0;
List<Bitmap> bmps = new ArrayList<Bitmap>();
for (int i = 0; i < itemscount; i++) {
View childView = adapter.getView(i, null, listview);
childView.measure(View.MeasureSpec.makeMeasureSpec(listview.getWidth(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
childView.layout(0, 0, childView.getMeasuredWidth(), childView.getMeasuredHeight());
childView.setDrawingCacheEnabled(true);
childView.buildDrawingCache();
bmps.add(childView.getDrawingCache());
allitemsheight+=childView.getMeasuredHeight();
}
Bitmap bigbitmap = Bitmap.createBitmap(listview.getMeasuredWidth(), allitemsheight, Bitmap.Config.ARGB_8888);
Canvas bigcanvas = new Canvas(bigbitmap);
Paint paint = new Paint();
int iHeight = 0;
for (int i = 0; i < bmps.size(); i++) {
Bitmap bmp = bmps.get(i);
bigcanvas.drawBitmap(bmp, 0, iHeight, paint);
iHeight+=bmp.getHeight();
bmp.recycle();
bmp=null;
}
return bigbitmap;
}
My listview contains large number of items in it, so how can i convert the whole listview to pdf. All your suggestions are appreciated
You can get the number of items displayed on screen in recyclerView, so create bitmap for first set of views, after that you can dynamically scroll to item below the last item displayed (i.e noOfItemDisplayed+1), again get bitmap, likewise all get all bitmaps into ArrayList<Bitmap> from which you can create pdf file, refer to code below to create pdf from arraylist of bitmaps:
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void createPdf() throws IOException {
PdfDocument document = new PdfDocument();
PdfDocument.Page page = null;
// crate a page description
for (int i = 0; i < bitmaps.size(); i++) {
Bitmap bitmap = bitmaps.get(i);
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(1400, 1979, i).create();
// start a page
page = document.startPage(pageInfo);
if (page == null) {
return;
}
Canvas canvas = page.getCanvas();
canvas.drawBitmap(bitmap, 0, 0, null);
document.finishPage(page);
}
// finish the page
// write the document content
fileHandler = new FileHandler(this, getString(R.string.app_name));
File pdf = fileHandler.getNewFileToWrite(AppConstants.FileExtensions.PDF); //crete and get file
try {
document.writeTo(new FileOutputStream(pdf));
} catch (IOException e) {
logger.error(e);
}
// close the document
document.close();
}
Now you can create a Bitmap for all childviews in the ListView.
After that, please process Bitmap as you like.
public List<Bitmap> getWholeListViewItemsToBitmap(ListView lv, Adapter adapter) {
List<Bitmap> listBitmap = new ArrayList<Bitmap>();
int itemsCount = adapter.getCount();
int lvViewLines = lv.getChildCount();
for(int from = 0; from < itemsCount; from+= lvViewLines) {
int to = from + lvViewLines;
for(int i = from; i < to && i < itemsCount; i++) {
View childView = adapter.getView(i, null, lv);
childView.measure(View.MeasureSpec.makeMeasureSpec(lv.getWidth(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
childView.layout(0, 0, childView.getMeasuredWidth(), childView.getMeasuredHeight());
childView.setDrawingCacheEnabled(true);
childView.buildDrawingCache();
listBitmap.add(childView.getDrawingCache());
}
lv.setScrollY(lvViewLines);
}
return listBitmap;
}
I'm having quite a problem here.
When I read image and then save it, I get the same picture. But when I open the pixel value, the value of each pixel is slightly different(larger or smaller around 10 units).
Why did that pixel change? I only read the image, then save it, I don't make changes to the pixel. I create it with format RGB and save as a PNG with ByteArrayOutputStream method.
private void onCaptureImageResult(Intent data) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
File destination = new File(Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
FileOutputStream fo;
try {
destination.createNewFile();
fo = new FileOutputStream(destination);
fo.write(bytes.toByteArray());
fo.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
ivImage.setImageBitmap(thumbnail);
}
private void onSelectFromGalleryResult(Intent data) {
Bitmap bm=null;
if (data != null) {
try {
bm = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
}
bmp = bm;
}
public void save(View view){
operation= Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(),bmp.getConfig());
int size = bmp.getRowBytes() * bmp.getHeight();
bytearrayoutputstream = new ByteArrayOutputStream();
int[] gambarR = new int[size];
int[] gambarG = new int[size];
int[] gambarB = new int[size];
int[] gambarA = new int[size];
int k = 0;
for(int i=0; i<bmp.getWidth(); i++){
for(int j=0; j<bmp.getHeight(); j++){
int p = bmp.getPixel(i, j);
gambarR[k] = Color.red(p);
gambarG[k] = Color.green(p);
gambarB[k] = Color.blue(p);
gambarA[k] = Color.alpha(p);
k++;
}
}
int l = 0;
for(int i = 0; i<bmp.getWidth(); i++){
for(int j = 0; j<bmp.getHeight();j++){
operation.setPixel(i, j, Color.rgb(gambarR[l], gambarG[l], gambarB[l]));
l++;
}
}
String fileName = "_hasil.bmp";
Long tsLong = System.currentTimeMillis()/1000;
String ts = tsLong.toString();
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
File gambar = new File(baseDir + File.separator + ts + fileName);
try
{
gambar.createNewFile();
fileoutputstream = new FileOutputStream(gambar);
fileoutputstream.write(bytearrayoutputstream.toByteArray());
fileoutputstream.close();
}
catch (Exception e)
{
e.printStackTrace();
}
ivImage.setImageBitmap(operation);
}
I will show you the difference between the image. I only read and save, and don't change the pixel. I need the pixel didn't change when I save it back.
As others have noticed, much of the code that you posted appears to do not much useful, indicating that you either haven't read the documentation, or haven't thought through the problem thoroughly.
However, the specific problem appears to be that you are saving your image in a lossy compression format (JPEG), in this case, at 90% quality. "Lossy" means that by definition you will never get back exactly the bitmap that you had before compression. Even setting JPEG quality to 100% is unlikely to get you exactly the same bitmap as before compression.
If you want exactly the same values back when reading the file, you'll need to write a lossless format, such as PNG or BMP.
We are developing an Android application and using ZXing for scanning QR codes. Is there a way to get full frame of decoded QR code using ZXing ?
Following method is added to PlanarYUVLuminanceSource class.
public void saveFrame() {
try {
YuvImage image = new YuvImage(yuvData, ImageFormat.NV21, getWidth(), getHeight(), null);
File file = new File(Environment.getExternalStorageDirectory().getPath() + "/frame.jpeg");
FileOutputStream fos = new FileOutputStream(file);
image.compressToJpeg(new Rect(0, 0, image.getWidth(), image.getHeight()), 100, fos);
} catch (FileNotFoundException e) {
Log.e(TAG, "FileNotFoundException!");
}
}
Called within DecodeHandler class as below,
private void decode(byte[] data, int width, int height) {
long start = System.currentTimeMillis();
Result rawResult = null;
PlanarYUVLuminanceSource source = CameraManager.get()
.buildLuminanceSource(data, width, height);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
rawResult = multiFormatReader.decodeWithState(bitmap);
} catch (ReaderException re) {
// continue
} finally {
multiFormatReader.reset();
}
if (rawResult != null) {
// Don't log the barcode contents for security.
long end = System.currentTimeMillis();
Log.d(TAG, "Found barcode in " + (end - start) + " ms");
Message message = Message.obtain(activity.getHandler(),
R.id.zxinglib_decode_succeeded, rawResult);
Bundle bundle = new Bundle();
bundle.putParcelable(DecodeThread.BARCODE_BITMAP,
source.renderCroppedGreyscaleBitmap());
source.saveFrame();
message.setData(bundle);
message.sendToTarget();
} else {
Message message = Message.obtain(activity.getHandler(),
R.id.zxinglib_decode_failed);
message.sendToTarget();
}
}
Here is result image,
Finally I found a solution. It is based on renderCroppedGreyscaleBitmap() method of PlanarYUVLuminanceSource class. Here is how I changed decode() method.
private void decode(byte[] data, int width, int height) {
long start = System.currentTimeMillis();
Result rawResult = null;
PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(data, width, height);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
rawResult = multiFormatReader.decodeWithState(bitmap);
} catch (ReaderException re) {
// continue
} finally {
multiFormatReader.reset();
}
if (rawResult != null) {
// Don't log the barcode contents for security.
long end = System.currentTimeMillis();
Log.d(TAG, "Found barcode in " + (end - start) + " ms");
// Grab & save frame
Bitmap wholeBmp = renderGrayScaleBitmap(data, width, height);
if(wholeBmp != null)
saveBitmap(wholeBmp, "frame.png");
else
Log.e(TAG, "Bitmap of frame is empty!");
Message message = Message.obtain(activity.getHandler(), R.id.zxinglib_decode_succeeded, rawResult);
Bundle bundle = new Bundle();
bundle.putParcelable(DecodeThread.BARCODE_BITMAP, source.renderCroppedGreyscaleBitmap());
message.setData(bundle);
message.sendToTarget();
} else {
Message message = Message.obtain(activity.getHandler(), R.id.zxinglib_decode_failed);
message.sendToTarget();
}
}
Create bitmap from decode data
private Bitmap renderGrayScaleBitmap(byte[] data, int width, int height) {
int[] pixels = new int[width * height];
int inputOffset = width;
for (int y = 0; y < height; y++) {
int outputOffset = y * width;
for (int x = 0; x < width; x++) {
int grey = data[inputOffset + x] & 0xff;
pixels[outputOffset + x] = 0xFF000000 | (grey * 0x00010101);
}
inputOffset += width;
}
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
Save bitmap to sdcard
private void saveBitmap(Bitmap bmp, String name) {
FileOutputStream out = null;
try {
String filename = Environment.getExternalStorageDirectory().toString() + "/" + name;
Log.i(TAG, "writtenPath=" + filename);
out = new FileOutputStream(filename);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
In my app I have to upload selected images to parse.com for taking their Printout . I have to maintain image quality and I could not resize the images.
I have to upload images in the parse.com ..I do not need to show them on device screen (images are form image gallery or from facebook album..or from sdcard) . I could not scale down them as per requirement.
I am getting OutOfMemory error on BitmapFactory.decodeFile(). How to solve this bug ?
is using android:largeHeap="true" could sove my issue ?
I am getting this crash on Samsung SM-G900T, But not on emulator ..
I tried to put
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inPreferredConfig = Config.RGB_565;
But it is not working.
Below is my AsyncTask class for uploading images to Parse.com
class UploadFileFromURL extends AsyncTask<String, String, String> {
ProgressDialog dialog;
String albumId = "";
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... f_url) {
try {
for (int i = 0; i < arrListImgBean.size(); i++) {
if (!isUploading || objAsyncUpload.isCancelled()) {
break;
}
try {
if (arrListImgBean.get(i).imageStatus == 1)
continue;
else if (arrListImgBean.get(i).imageStatus == 2) {
isPhotodeleted = true;
publishProgress("" + countUploaded);
deletePhoto(i);
}
else {
isPhotodeleted = false;
try {
Bitmap b = null;
InputStream is = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inPreferredConfig = Config.RGB_565; // to
// reduce
// the
// memory
options.inDither = true;
if (arrListImgBean.get(i).imgURL
.startsWith("http")) {
try {
URL url = new URL(
arrListImgBean.get(i).imgURL);
is = url.openConnection()
.getInputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
b = BitmapFactory.decodeStream(is, null,
options);
} else {
b = BitmapFactory.decodeFile(
arrListImgBean.get(i).imgURL,
options);
}
// Convert it to byte
ByteArrayOutputStream stream = new ByteArrayOutputStream();
// Bitmap out = Bitmap.createScaledBitmap(b,
// 1500, 2100, false);
b.compress(Bitmap.CompressFormat.PNG, 100,
stream);
byte[] image = stream.toByteArray();
ParseFile file = new ParseFile("Android.png",
image);
file.save();
String uploadedUrl = file.getUrl();
if (uploadedUrl != null) {
ParseObject imgupload = new ParseObject(
"Photo");
imgupload.put("userName", ParseUser
.getCurrentUser().getEmail());
imgupload.put("photoURL", file);
imgupload.put("photoID",
arrListImgBean.get(i).imageId);
imgupload.put("count", 1);
imgupload.put("albumName", albumId);
imgupload.save();
String objId = imgupload.getObjectId();
if (objId != null && !objId.isEmpty()) {
countUploaded++;
publishProgress("" + countUploaded);
database.updateImageStatus(
arrListImgBean.get(i).imageId,
Constants.STATUS_UPLOADED,
objId, uploadedUrl);
}
}
} catch (Exception e) {
}
}
} catch (Exception e) {
isUploading = false;
e.printStackTrace();
}
}
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(String file_url) {
// dismissDialog(progress_bar_type);
isUploading = false;
btnUploadImages.setBackgroundResource(R.drawable.upload_photo);
vprogress.setCompoundDrawables(null, null, null, null);
// stopLoading();
setProgressMsg();
}
}
android:largeHeap="true"
This line of code can solve your problem but its a temporary solution but crash may occurs again if number of images or the size of images will increase. Better to Use Picasso library to deals with Images
Consider you have an image of 1024x1024dp and a device with 512x512dp (both figures are just for understanding). So, in this case, loading a full resolution image on a smaller scale device is waste of memory. What you can do is to scale down the image so that it fits the device screen. In this way not only you will save a lot of memory but also get a proper, clear and sharp image.
I am adding code for scaling the image which I am using currently in my project.
final FileInputStream streamIn = new FileInputStream(file);
final BitmapFactory.Options ops = new BitmapFactory.Options();
ops.inJustDecodeBounds = true;
// Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 300;
int width_tmp = ops.outWidth, height_tmp = ops.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) {
break;
}
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
ops.inJustDecodeBounds = false;
ops.inSampleSize = scale;
bitmap = BitmapFactory.decodeStream(streamIn, null, ops); //This gets the image
streamIn.close();
Choose a REQUIRED_SIZE value depending on the device's screen display size.
try {
image = readInFile(path);
}
catch(Exception e) {
e.printStackTrace();
}
// Create the ParseFile
ParseFile file = new ParseFile("picturePath", image);
// Upload the image into Parse Cloud
file.saveInBackground();
// Create a New Class called "ImageUpload" in Parse
ParseObject imgupload = new ParseObject("Image");
// Create a column named "ImageName" and set the string
imgupload.put("Image", "picturePath");
// Create a column named "ImageFile" and insert the image
imgupload.put("ImageFile", file);
// Create the class and the columns
imgupload.saveInBackground();
// Show a simple toast message
Toast.makeText(LoadImg.this, "Image Saved, Upload another one ",Toast.LENGTH_SHORT).show();
private byte[] readInFile(String path) throws IOException {
// TODO Auto-generated method stub
byte[] data = null;
File file = new File(path);
InputStream input_stream = new BufferedInputStream(new FileInputStream(
file));
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
data = new byte[16384]; // 16K
int bytes_read;
while ((bytes_read = input_stream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, bytes_read);
}
input_stream.close();
return buffer.toByteArray();
}