Getting a black preview and a image after onPictureTaken - java

I m trying to develop an app which would auto crop the edges of a card which is detected by using opencv.
Here in this function i am doing the following :
1) Converting the byte array (ie data) into a bitmap and then to a Mat
2) Cropping the required portion of the card and re sizing it
3) Converting the mat back into a byte array
4) Saving the modified byte array in a File(jpg)
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Mat mat=new Mat();
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
Utils.bitmapToMat(bmp, mat); //converting a mat to bitmap
Mat matCrop = mat.submat((int)p1.y,(int)p2.y,(int)p3.x,(int)p4.x);//surely no issues here
Imgproc.resize(matCrop, matCrop, mat.size());
byte[] imageInBytes = new byte[(int)(matCrop.total() * matCrop.channels())];
mat.get(0, 0, imageInBytes);
data=imageInBytes;
try {
FileOutputStream fos = new FileOutputStream(mPictureFileName);
fos.write(data);
fos.close();
} catch (java.io.IOException e) {}
}
The picture gets saved in memory but the preview as well as the image both are blank . The saved file also takes about 3.5 Mb , What could be the reason for this ?
Thanks in advance.

Related

Image generation failure through modified byte array using both java and opencv?

In my program I am reading an image using java, taking its byte array and applying modifications to it by applying random functions. Now during the entire process the size of array is maintained but when I am trying to construct an image using the byte array an empty image is obtained. I have tried using both java and opencv to reconstruct the image (the image is grayscale image of 440*442 size .png type).
opencv code:
byte[] bytesArrayForImage=new byte[array.length];
for (int i=0; i<array.length; i++) {
bytesArrayForImage[i] = (byte) Integer.parseInt(array[i]);
}
Mat mat = new Mat(440,442, CvType.CV_8UC1);
mat.put(0,0, bytesArrayForImage);
String filename111 = Path;
Highgui.imwrite(filename111, mat);
java code:
BufferedImage image=ImageIO.read(new ByteArrayInputStream(bytearray));
ImageIO.write(image, "png", new File(C:\\Users\\domin\\Desktop\\Sop\\,"modified.png"));

converting from byte array to drawable image gives corrupt image: Android

I am converting an image into a byte array. Sending it over a socket, then once it is through the socket, I need to convert it back to a drawable, png, or any type of image that I can use as the background of an image button. The problem is that when I either convert into a byte array, or from an array into a drawable, the file is getting corrupted.
I am getting my original image from the last installed app on my phone as follows and then I am saving it to a file on the phone so I can check that at this point the image file is successfully captured (and it is. Nothing is corrupt at this point):
final PackageManager pm = context.getPackageManager();
ApplicationInfo ai = pm.getApplicationInfo(intent.getData().getSchemeSpecificPart(), 0);
Drawable icon = context.getPackageManager().getApplicationIcon(ai);
BitmapDrawable bitmapIcon = (BitmapDrawable)icon;
FileOutputStream fosIcon = context.openFileOutput(applicationName + ".png", Context.MODE_PRIVATE);
bitmapIcon.getBitmap().compress(Bitmap.CompressFormat.PNG, 100, fosIcon);
InputStream inputStream = context.openFileInput(applicationName + ".png");
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
// GET FILE DIRECTORY
File imageFile = new File(context.getFilesDir(), applicationName + ".png");
Now I am converting this bitmap to a byte array to send over the socket:
// get bitmap image in bytes to send
int bytes = bitmap.getByteCount();
Log.d("tag_name", "Number of Bytes" + bytes);
ByteBuffer buffer = ByteBuffer.allocate(bytes); //Create a new buffer
bitmap.copyPixelsToBuffer(buffer); //Move the byte data to the buffer
byte[] array = buffer.array();
Log.d("tag_name", "array" + array);
int start=0;
int len=array.length;
Log.d("tag_name", "length" + len);
new SendToClient(array, applicationName, len, start).execute();
At this point I know my file is successfully getting saved as this image:
Then, in SendToClient, I am using DataOutputStream to send over the array. I am not posting this code, because I have tested that sending the data is not where the problem occurs. If I don't send the byte array, and convert from the byte array back to a drawable in this same activity, it is also corrupt.
Here is how I convert from an array back to a drawable after using DataInputStream to read the array that was sent:
YuvImage yuvimage=new YuvImage(array, ImageFormat.NV21, 100, 100, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
yuvimage.compressToJpeg(new Rect(0, 0, 100, 100), 80, baos);
byte[] jdata = baos.toByteArray();
// Convert to Bitmap
Bitmap bmp = BitmapFactory.decodeByteArray(jdata, 0, jdata.length);
Log.d("tag_name", "bmp" + bmp);
// convert bitmap to drawable
final Drawable d = new BitmapDrawable(context.getResources(), bmp);
The reason I am first compressing to a JPEG is because if I only used BitmapFactory.decodeByteArray, then I would get "bmp = null", converting to JPEG first was the only solution I found where I could get a bitmap that wasn't null, but now my image is corrupt. This is what Drawable d looks like:
Try the following code,
Convert Bitmap to ByteArray.
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.myImage);
ByteArrayOutputStream opstream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, opstream);
byte[] bytArray = opstream.toByteArray();
Convert ByteArray to Bitmap.
Bitmap bitmap = BitmapFactory.decodeByteArray(bytArray, 0, bytArray.length);
ImageView img = (ImageView) findViewById(R.id.imgv1);
img.setImageBitmap(bitmap);
This may helps you.

Java - Convert RAW to JPG/PNG

I have an image captured by a camera, in RAW BGRA format (byte array).
How can I save it to disk, as a JPG/PNG file?
I've tried with ImageIO.write from Java API, but I got error IllegalArgumentException (image = null)
CODE:
try
{
InputStream input = new ByteArrayInputStream(img);
BufferedImage bImageFromConvert = ImageIO.read(input);
String path = "D:/image.jpg";
ImageIO.write(bImageFromConvert, "jpg", new File(path));
}
catch(Exception ex)
{
System.out.println(ex.toString());
}
Note that "img" is the RAW byte array, and that is NOT null.
The problem is that ImageIO.read does not support raw RGB (or BGRA in your case) pixels. It expects a file format, like BMP, PNG or JPEG, etc.
In your code above, this causes bImageFromConvert to become null, and this is the reason for the error you see.
If you have a byte array in BGRA format, try this:
// You need to know width/height of the image
int width = ...;
int height = ...;
int samplesPerPixel = 4;
int[] bandOffsets = {2, 1, 0, 3}; // BGRA order
byte[] bgraPixelData = new byte[width * height * samplesPerPixel];
DataBuffer buffer = new DataBufferByte(bgraPixelData, bgraPixelData.length);
WritableRaster raster = Raster.createInterleavedRaster(buffer, width, height, samplesPerPixel * width, samplesPerPixel, bandOffsets, null);
ColorModel colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
BufferedImage image = new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null);
System.out.println("image: " + image); // Should print: image: BufferedImage#<hash>: type = 0 ...
ImageIO.write(image, "PNG", new File(path));
Note that JPEG is not a good format for storing images with alpha channel. While it is possible, most software will not display it properly. So I suggest using PNG instead.
Alternatively, you could remove the alpha channel, and use JPEG.
With Matlab you can convert all types of images with 2 lines of code:
img=imread('example.CR2');
imwrite(img,'example.JPG');

Sample down Image from Inputstream without decoding to Bitmap

I am trying to find a solution to be able to download an image from Url into the Filesystem and resize it without the need to decode it to a bitmap first.
The only solution I could find yet was the approach to decode it to a bitmap with specific SampleSize. However, the problem here is that a lot of memory is consumed when creating the bitmap which would limit the maximum size of the image depending on the free memory available on the device. Another Problem is that it takes a lot of time to decode it to a Bitmap and also to compress it back to an output stream.
My current code looks like this (options1 contains the original dimensions, calculateSampleSizeForImageSize() calculates the sampleSize for smaller required Imagesize):
if (maximumImageSize < Runtime.getRuntime().maxMemory() / 4f) {
//enough memory free to reduce size
//reduce size
BitmapFactory.Options options2 = new BitmapFactory.Options();
options2.inSampleSize = calculateSampleSizeForImageSize(options1, maximumImageSize);
options2.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeStream(is, null, options2);
try {
//write reduced size bitmap to picture file
os = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
os.flush();
bitmap.recycle();
return 0;
} catch (IOException e) {
Log.d(TAG, "failed to fetch image", e);
throw new IOException(e);
} finally {
closeStream(os);
closeStream(is);
}
So is there a way to bypass the bitmap and directly write the input stream in reduced size to the output stream?

Convert OpenCV Mat object to BufferedImage

I am trying to create a helper function using OpenCV Java API that would process an input image and return the output byte array. The input image is a jpg file saved in the computer. The input and output image are displayed in the Java UI using Swing.
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
// Load image from file
Mat rgba = Highgui.imread(filePath);
Imgproc.cvtColor(rgba, rgba, Imgproc.COLOR_RGB2GRAY, 0);
// Convert back to byte[] and return
byte[] return_buff = new byte[(int) (rgba.total() * rgba.channels())];
rgba.get(0, 0, return_buff);
return return_buff;
When the return_buff is returned and converted to BufferedImage I get NULL back. When I comment out the Imgproc.cvtColor function, the return_buff is properly converted to a BufferedImage that I can display. It seems like the Imgproc.cvtColor is returning a Mat object that I couldn't display in Java.
Here's my code to convert from byte[] to BufferedImage:
InputStream in = new ByteArrayInputStream(inputByteArray);
BufferedImage outputImage = ImageIO.read(in);
In above code, outputImage is NULL
Does anybody have any suggestions or ideas?
ImageIO.read(...) (and the javax.imageio package in general) is for reading/writing images from/to file formats. What you have is an array containing "raw" pixels. It's impossible for ImageIO to determine file format from this byte array. Because of this, it will return null.
Instead, you should create a BufferedImage from the bytes directly. I don't know OpenCV that well, but I'm assuming that the result of Imgproc.cvtColor(rgba, rgba, Imgproc.COLOR_RGB2GRAY, 0) will be an image in grayscale (8 bits/sample, 1 sample/pixel). This is the same format as BufferedImage.TYPE_BYTE_GRAY. If this assumption is correct, you should be able to do:
// Read image to Mat as before
Mat rgba = ...;
Imgproc.cvtColor(rgba, rgba, Imgproc.COLOR_RGB2GRAY, 0);
// Create an empty image in matching format
BufferedImage gray = new BufferedImage(rgba.width(), rgba.height(), BufferedImage.TYPE_BYTE_GRAY);
// Get the BufferedImage's backing array and copy the pixels directly into it
byte[] data = ((DataBufferByte) gray.getRaster().getDataBuffer()).getData();
rgba.get(0, 0, data);
Doing it this way, saves you one large byte array allocation and one byte array copy as a bonus. :-)
I used this kind of code to convert Mat object to Buffered Image.
static BufferedImage Mat2BufferedImage(Mat matrix)throws Exception {
MatOfByte mob=new MatOfByte();
Imgcodecs.imencode(".jpg", matrix, mob);
byte ba[]=mob.toArray();
BufferedImage bi=ImageIO.read(new ByteArrayInputStream(ba));
return bi;
}

Categories

Resources