saving image is taking too long android - android

I use this code to save an image, but it takes a long time. Sometimes it takes 10 second or more. I have decreased the bitmap size and it helps. But it also decreases the quality. How can I save bitmap in its original size without decrease in quality and fast?
String imageName = UUID.randomUUID().toString();
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root, "/removeBG");
if (!myDir.exists()) {
myDir.mkdirs();
}
String fname;
if (imgBackground.getDrawable() != null)
fname = imageName + ".jpg";
else
fname = imageName + ".png";
File file = new File(myDir, fname);
if (file.exists()) {
file.delete();
}
try {
file.createNewFile(); // if file already exists will do nothing
FileOutputStream out = new FileOutputStream(file);
bitmap = CropBitmapTransparency(bitmap);
bitmap = resizeBitmap(bitmap, MAX_SIZE, MAX_SIZE);
if (imgBackground.getDrawable() != null)
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
else
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
MediaScannerConnection.scanFile(this, new String[]{file.toString()}, new String[]{file.getName()}, null);
I search this problem and find a soultion like this :
public static void create(OutputStream os,int cols,int rows,int r,int g,int b,int a) {
ImageInfo imi = new ImageInfo(cols, rows, 8, true); // 8 bits per channel, alpha
PngWriter png = new PngWriter(os, imi);
// just a hint to the coder to optimize compression+speed:
png.setFilterType(FilterType.FILTER_NONE);
ImageLineByte iline = new ImageLineByte (imi);
byte[] scanline = iline.getScanlineByte();// RGBA
for (int col = 0,pos=0; col < imi.cols; col++) {
scanline[pos++]=(byte) r;
scanline[pos++]=(byte) g;
scanline[pos++]=(byte) b;
scanline[pos++]=(byte) a;
}
for (int row = 0; row < png.imgInfo.rows; row++) {
png.writeRow(iline);
}
png.end();
}
I am too confused. I don't know how to use it.

MediaStore.Images.Media.insertImage (getContext ().getContentResolver (),
imgBitmap, nameFull.getText ().toString ().trim (),
"");
Try this using your own variable names. This worked for me

Related

I get different pixel value after reading and writing the image

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.

Getting bitmap from external storage

I have saved a bitmap to external storage via FileOutputStream and am trying to retrieve that file in another class so that it can be put into a imageView. Here is where I save the bitmap:
public void SaveImage(Bitmap default_b) {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 100000;
n = generator.nextInt(n);
String fname = "Image-" + n +".png";
File file = new File (myDir, fname);
Log.i("AppInfoAdapter", "" + file);
if (file.exists()) file.delete();
try {
// File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
// + "/" + fname + ".png");
// FileOutputStream out = mContext.getApplicationContext().openFileOutput("bitmapA", Context.MODE_WORLD_WRITEABLE);
FileOutputStream out = new FileOutputStream(file);
default_b.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
and I am trying to recieve it here:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Try to reuse the views
ImageView view = (ImageView) convertView;
// if convert view is null then create a new instance else reuse it
if (view == null) {
view = new ImageView(Context);
Log.d("GridViewAdapter", "new imageView added");
}
try {
FileInputStream in = Context.openFileInput("bitmapA");
BufferedInputStream buf = new BufferedInputStream(in);
byte[] bitMapA = new byte[buf.available()];
buf.read(bitMapA);
Bitmap bM = BitmapFactory.decodeByteArray(bitMapA, 0, bitMapA.length);
view.setImageBitmap(bM);
if (in != null) {
in.close();
}
if (buf != null) {
buf.close();
}
} catch (Exception e) {
e.printStackTrace();
}
view.setImageResource(drawables.get(position));
view.setScaleType(ImageView.ScaleType.CENTER_CROP);
view.setLayoutParams(new android.widget.GridView.LayoutParams(70, 70));
view.setTag(String.valueOf(position));
return view;
}
I have done plenty of searching on this and have come across multiple ways of doing the same thing but for at the moment, this way of doing it doesn't work.
I have seen it where you use openFileOutput and openFileInput and then I have also seen where people just create new FileInput and Output streams.
Which one is better to use for the bitmap?
and then depending on which one is better to use (since I have both set up for when I save the bitmap), how can I get that bitmap from external storage?
Thanks!

Android: Saving bitmaps to library

I've created an app that loops through two bitmaps and store the pixel data into 2D arrays (compare1[][] & compare2[][]).
I believe my code is working to some extent. It looks like it saves the Bitmap but when I go to the gallery later its not there. Any ideas would be greatly appreciated; here is a sample of my code:
public void getPixels(int[][] compare2,int[][]compare1, int x)
{
Bitmap difference = Bitmap.createBitmap(width, height, Config.ARGB_8888);
for(int i = 0; i<width-1; i++)
{
for(int j=0; j<height-1; j++)
{
int mColor = BIT.get(x).getPixel(i, j);
int alpha = Color.alpha(mColor);
int red = Color.red(mColor);
int green = Color.green(mColor);
int blue = Color.blue(mColor);
int xAvg = ((red+green+blue)/3);
compare2[i][j] = xAvg;
if ((compare1[i][j] - compare2[i][j]) < 50)
{
difference.setPixel(i, j, -16777216);
//System.out.println("No Significant Change");
}
else
{
difference.setPixel(i, j, -1);
//System.out.println("Change");
}
}
}
try {
String path = Environment.getExternalStorageDirectory().toString();
OutputStream fOut = null;
File file = new File(path,"Test.jpg");
fOut = new FileOutputStream(file);
difference.compress(Bitmap.CompressFormat.JPEG, 80, fOut);
fOut.flush();
fOut.close();
fOut = null;
} catch (Exception e) {
e.printStackTrace();
}
}
After you've saved the Image, you need to invoke the MediaScanner for the image to appear in the gallery:
Intent intent = new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory());
sendBroadcast(intent);
A detailed tutorial: Trigger Media Scanner.
Related question on SO:How update the android media database

Android ZXing Get Barcode Image

I am using Zxing library to generate a barcode in my Android application
Intent intent = new Intent("com.google.zxing.client.android.ENCODE");
intent.putExtra("ENCODE_FORMAT", "UPC_A");
intent.putExtra("ENCODE_DATA", "55555555555");
startActivityForResult(intent,0);
Is there anyway to save the generated image in my application which is calling Zxing? I see that in my onActivityResult I get intent null.
Thanks in advance for your help
Take the views cache and save it in bitmap something like this
View myBarCodeView = view.getRootView()
//Else this might return null
myBarCodeView.setDrawingCacheEnabled(true)
//Save it in bitmap
Bitmap mBitmap = myBarCodeView.getDrawingCache()
OR
draw your own barcode or QR CODE
//Change the writers as per your need
private void generateQRCode(String data) {
com.google.zxing.Writer writer = new QRCodeWriter();
String finaldata =Uri.encode(data, "ISO-8859-1");
try {
BitMatrix bm = writer.encode(finaldata,BarcodeFormat.QR_CODE, 350, 350);
mBitmap = Bitmap.createBitmap(350, 350, Config.ARGB_8888);
for (int i = 0; i < 350; i++) {
for (int j = 0; j < 350; j++) {
mBitmap.setPixel(i, j, bm.get(i, j) ? Color.BLACK: Color.WHITE);
}
}
} catch (WriterException e) {
e.printStackTrace();
}
if (mBitmap != null) {
mImageView.setImageBitmap(mBitmap);
}
}
public void generateBarCode(String data){
com.google.zxing.Writer c9 = new Code128Writer();
try {
BitMatrix bm = c9.encode(data,BarcodeFormat.CODE_128,350, 350);
mBitmap = Bitmap.createBitmap(350, 350, Config.ARGB_8888);
for (int i = 0; i < 350; i++) {
for (int j = 0; j < 350; j++) {
mBitmap.setPixel(i, j, bm.get(i, j) ? Color.BLACK : Color.WHITE);
}
}
} catch (WriterException e) {
e.printStackTrace();
}
if (mBitmap != null) {
mImageView.setImageBitmap(mBitmap);
}
}
Once you get the bitmap image just save it
//create a file to write bitmap data
File f = new File(FilePath, FileName+".png");
f.createNewFile();
//Convert bitmap to byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageBitmap.compress(CompressFormat.PNG, 0, bos);
byte[] bytearray = bos.toByteArray();
//Write bytes in file
FileOutputStream fos = new FileOutputStream(f);
fos.write(bytearray);
fos.flush();
fos.close();
You can also check a small library from github that i had created to create Barcode or QR Code
GZxingEncoder Encoder = GZxingEncoder.getInstance();
Encoder.initalize(this);
//To generate bar code use this
Bitmap bitmap = Encoder.generateBarCode_general("some text")
It is not returned in the Intent right now. There's no way to get it. You could suggest a patch to make it be returned -- it is probably a couple days' work. Or try Girish's approach, which is just to embed the encoding directly.
To store the scanned image in ZXing, You have to override a method drawResultPoints in Class CaptureActivity.
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root);
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-"+ n +".jpg";
File file = new File (myDir, fname);
if (file.exists ()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
barcode.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
This will saved the scanned image in the root directory of SD card, you can customize it to save it in any particular folder you need. The image it will be storing is the scanned image which appears as a ghost image while you scan.

screen shot for the activity

i want to create a bitmap of whats being currently displayed of my app, one thing i went into is cant read FB buffer requires root, would like to know if it is possible to create a image file for the screen, please i want the help to code this, no 3rd party intents , thanks, answers would be much appreciated
From your Activity (pseudo-code):
Bitmap bm = Bitmap.create...
Canvas canvas = new Canvas(bm);
getWindow.getDecorView().draw(canvas);
You can use FFMPEG to capture the Screen
Try this.....
{
LinearLayout view = (LinearLayout) findViewById(R.id.imageLayout);
View v1 = view.getRootView();
v1.setDrawingCacheEnabled(true);
String dir="myimages";
Bitmap bm = v1.getDrawingCache();
saveBitmap(bm, dir, "capturedimage");
}
static String saveBitmap(Bitmap bitmap, String dir, String baseName) {
try {
File sdcard = Environment.getExternalStorageDirectory();
File pictureDir = new File(sdcard, dir);
pictureDir.mkdirs();
File f = null;
for (int i = 1; i < 200; ++i) {
String name = baseName + i + ".png";
f = new File(pictureDir, name);
if (!f.exists()) {
break;
}
}
System.out.println("Image size : "+bitmap.getHeight());
if (!f.exists()) {
String name = f.getAbsolutePath();
FileOutputStream fos = new FileOutputStream(name);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
System.out.println("After File Size : "+f.length());
fos.flush();
fos.close();
return name;
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("Exception in saveBitmap: "+e.getMessage());
} finally {
}
return null;
}

Categories

Resources