Scrambled images after calling Camera.takepicture() on HTC Incredible - android

Taking picture by calling Camera.takepicture() on HTC Incredible results in getting scrambled images. This problem does not appear on any other devices I´ve tested my application(Galaxy SII, Galaxy S, Nexus S). I haven´t been able to find the solution on my own as of yet...
Image linked: http://i.stack.imgur.com/j4VE8.jpg (need more reputation to post it)
This is how I save my imageData:
static boolean StoreByteImage(Context mContext, byte[] imageData,
int quality, String expName) {
File sdImageMainDirectory = new File("/sdcard");
FileOutputStream fileOutputStream = null;
//String nameFile;
try {
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap myImage = BitmapFactory.decodeByteArray(imageData, 0,
imageData.length,options);
fileOutputStream = new FileOutputStream(
sdImageMainDirectory.toString() +"/CapturedQRCode.jpg");
BufferedOutputStream bos = new BufferedOutputStream(
fileOutputStream);
myImage.compress(CompressFormat.PNG, quality, bos);
bos.flush();
bos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
Anyone got a hint?

Related

Android: Compress a bitmap with few ram abuse

when I call
BitmapFactory.decodeFile(filepath);
I have an out of memory error because the file is too big.
How can I compress this file without abusing of the ram and without scaling it?
Please, help me =(
this is what i could do for now (i found this code here on stack)
bm = BitmapFactory.decodeFile(filepath);
File compressedFilePicture;
try {
compressedFilePicture = createImageFile();
FileOutputStream fOut = new FileOutputStream(compressedFilePicture);
bm.compress(CompressFormat.JPEG, COMPRESS_VALUE, fOut);
new File(filepath).delete();
filepath = compressedFilePicture.getAbsolutePath();
bm = BitmapFactory.decodeFile(filepath);
imageview.setImageBitmap(bm);
sc.string = filepath;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I need to load the bitmap on ram a slice a time.. any idea??
bm = BitmapFactory.decodeFile(filepath);
File compressedFilePicture;
try {
compressedFilePicture = createImageFile();
FileOutputStream fOut = new FileOutputStream(compressedFilePicture);
bm.compress(CompressFormat.JPEG, COMPRESS_VALUE, fOut);
new File(filepath).delete();
filepath = compressedFilePicture.getAbsolutePath();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4; //u can use 2/4/8/16....ect
Uri uri = getImageUri(filepath);
InputStream in = in = contentResolver.openInputStream(uri);
bm = BitmapFactory.decodeStream(in, null, options);
imageview.setImageBitmap(bm);
sc.string = filepath;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Prevent bitmap being written to disk being scaled

I'm having an issue whereby when I write a bitmap to disk, it gets written to disk, however it gets written as a miniscule image (3kb or less in filesize).
I have checked that the source image is indeed the correct dimensions, however the output image seems shrunk despite configuring the bitmap options to not scale.
#Override
protected Void doInBackground(PPImage... params) {
String filename = "pp_" + position + ".jpg";
File externalStorageDirectory = Environment.getExternalStorageDirectory();
final File destination = new File(externalStorageDirectory, filename);
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 16;
opts.inPurgeable = true;
opts.inScaled = false;
decode(opts, Uri.parse(params[0].getUri()), getActivity(), new OnBitmapDecodedListener() {
#Override
public void onDecoded(Bitmap bitmap) {
try {
FileOutputStream out = new FileOutputStream(destination, false);
writeImageToFileTask.this.holder.pathToImage = destination.getAbsolutePath();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
MediaStore.Images.Media.insertImage(getActivity().getContentResolver(), destination.getAbsolutePath(), destination.getName(), destination.getName());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
});
return null;
}
private void decode(BitmapFactory.Options options, Uri mUri, Context mContext, OnBitmapDecodedListener listener) {
try {
InputStream inputStream;
if (mUri.getScheme().startsWith("http") || mUri.getScheme().startsWith("https")) {
inputStream = new URL(mUri.toString()).openStream();
} else {
inputStream = mContext.getContentResolver().openInputStream(mUri);
}
Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options);
listener.onDecoded(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
}
How do I ensure that the image being written to file is the same dimensions as the original source image?
You have specified sample size in your code, which will result in resizing:
opts.inSampleSize = 16;
Just remove this line, and the dimension of the output image should be the same.
About the usage of inSampleSize, according to official doc:
For example, inSampleSize == 4 returns an image that is 1/4 the
width/height of the original, and 1/16 the number of pixels. Any value
<= 1 is treated the same as 1.

Android: Saving photo with image on photo

When I take a picture with my Android camera, there is an image (imageview3) on my screen that I want to save with my picture.
Here is my onPictureTaken method
public void onPictureTaken(byte[] data, Camera camera) {
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "/Ker");
imagesFolder.mkdirs();
String fileName = "Ker_.jpg";
output = new File(imagesFolder, fileName);
ImageView view = (ImageView) gameactivity.findViewById(R.id.imageView3);
view.setDrawingCacheEnabled(true);
Bitmap b = view.getDrawingCache();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(output);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
b.compress(CompressFormat.JPEG, 95, fos);
try {
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
camera.stopPreview();
}
When I open the folder, the picture saved is only the imageview3 with a black background. Why has the real camera view not been saved?
EDIT
I'm trying something with canvas too:
output = new File(imagesFolder, fileName);
ImageView view = (ImageView) gameactivity.findViewById(R.id.imageView3);
view.setDrawingCacheEnabled(true);
Bitmap b = view.getDrawingCache();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(output);
fos.write(data);
fos.close();
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
FileOutputStream fos2 = null;
b.compress(CompressFormat.JPEG, 95, fos2);
try {
Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fos.getFD());
Bitmap bitmap2 = BitmapFactory.decodeFileDescriptor(fos2.getFD());
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(bitmap2, null, null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Is that correct? How to save the canvas into a file on my sdcard (ie write data from canvas on fileoutputstream)
You're appending the JPEG of the imageview and the JPEG from the camera into a single file.
Create a separate file output stream for each file, and write the data from Bitmap.compress() and the onPictureTaken data array into their own streams.
If you want the two images to be combined into a single image, you'll need to decode the data array into a Bitmap, and then use a Canvas to draw the ImageView bitmap and the camera-captured Bitmap onto the canvas in the arrangement you want, and then save that out as a single jpeg.
You can't simply concatenate two compressed JPEG bitstreams together; the file format doesn't work that way.

Read images byte by byte from android internal storage takes too much time

I'm trying to display images from android internal storage, I have only 4images(the images are screen shots taked before), I display these images in a GridView, it works, but it takes too much time, this is my code :
FileInputStream fis = null;
DataOutputStream outWriter = null;
ByteArrayOutputStream bufStream = null;
String imageFile;
int occurence;
for (int i=0; i<4; i++) {
try {
occurence = i+1;
imageFile = "preview"+occurence+".png";
fis = openFileInput(imageFile);
bufStream = new ByteArrayOutputStream();
outWriter = new DataOutputStream(bufStream);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int ch;
byte[] data = null;
try {
**while((ch = fis.read()) != -1)
outWriter.write(ch);**
outWriter.close();
data = bufStream.toByteArray();
bufStream.close();
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
favorPreviews.add(BitmapFactory.decodeByteArray(data, 0, data.length)) ;
}
As you can see, I'm using FileInputStream to read them, but that reads the files byte by byte in this loop :
while((ch = fis.read()) != -1)
outWriter.write(ch);
And it takes too much time, is anyone know a faster way to read these images?
To be faster is indicated to reduced the image size. It can be done using the Bitmap decodeFile (String pathName, BitmapFactory.Options opts)
Look this example:
public Bitmap getReducedBitmap(String path) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inSampleSize=4; // reduced the image to 1/4 of the orignal size
return BitmapFactory.decodeFile(path, opt);
}
Use BitmapFactory.decodeFile(String) instead. Then all of this file reading is handled for you.

Saving image, webview, android

I am using webview in android to display images (mainly using google ajax API), Now if I want to save an image into local storage, How do I do ? I have image url, which can be used for saving.
If you have the image url, this is dead easy. You just have to retrieve the bytes of the image. Here is a sample that should help you :
try {
URL url = new URL(yourImageUrl);
InputStream is = (InputStream) url.getContent();
byte[] buffer = new byte[8192];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();
while ((bytesRead = is.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
return output.toByteArray();
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
This will return a byteArray that you can either store wherever you like, or reuse to create an image, by doing that :
Bitmap bm = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
I know this is a quite old but this is valid too:
Bitmap image = BitmapFactory.decodeStream((InputStream) new URL("Http Where your Image is").getContent());
With the Bitmap filled up, just do this to save to storage (Thanks to https://stackoverflow.com/a/673014/1524183)
FileOutputStream out;
try {
out = new FileOutputStream(filename);
image.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try{
out.close();
} catch(Throwable ignore) {}
}
IHMO much more cleaner and simpler than the accepted answer.

Categories

Resources