I'm working on an application to capture images but I'd like to rotate a JPEG image before saving it, I already saw this link :
Android Rotate Picture before saving
This is what I'm doing right now.
ByteBuffer byteBuffer = mImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(mImageFileName);
fileOutputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
I tried this to rotate the image like this :
// Bytes array to bitmap and matrix rotation
Bitmap sourceBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Matrix m = new Matrix();
m.setRotate((float)90, sourceBitmap.getWidth(), sourceBitmap.getHeight());
Bitmap targetBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight(), m, true);
// Bitmap to bytes array
int size = targetBitmap.getRowBytes() * targetBitmap.getHeight();
ByteBuffer targetByteBuffer = ByteBuffer.allocate(size);
targetBitmap.copyPixelsToBuffer(targetByteBuffer);
bytes = targetByteBuffer.array();
But when I look into the file into my gallery, I cannot read it, the image seems broken.
EDIT: Doesn't work on Android 7.1.1 :/ Any idea ? Can I do something similar for a video record?
You are Coverting Your Bitmap to bytes array,
Now You stop That way save Bitmap directly to File
Bitmap sourceBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Matrix m = new Matrix();
m.setRotate((float)90, sourceBitmap.getWidth(), sourceBitmap.getHeight());
Bitmap rotatedBitmap= Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight(), m, true);
// Save Bitmap directly to the file
String filename = "hello.jpg";
File sd = Environment.getExternalStorageDirectory();
File dest = new File(sd, filename);
try {
FileOutputStream out = new FileOutputStream(dest);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
This little change apparently did the trick ! Thanks Nikunj !
ByteBuffer byteBuffer = mImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Matrix matrix = new Matrix();
matrix.setRotate((float)90, bitmap.getWidth(), bitmap.getHeight());
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(mImageFileName);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
Related
I'm trying to save a Image type data as a jpg file to SD card, what I plan to do is first converting it to Bitmap, compress bitmap as jpeg format, then use FileOutputStream to save it to SD card.
Here's my code:
File imagefile = new File(sdCardPath, "image.jpg");
Image image = fromFrame.getImage();
ByteBuffer bbuffer = image.getPlanes()[0].getBuffer();
byte[] byts = new byte[bbuffer.capacity()];
bbuffer.get(byts);
Bitmap bitmapImage = BitmapFactory.decodeByteArray(byts, 0, byts.length, null);
try{
FileOutputStream out = new FileOutputStream(imagefile);
bitmapImage.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (FileNotFoundException e) {
Log.v(TAG, "FileNotFoundExceptionError " + e.toString());
} catch (IOException e) {
Log.v(TAG, "IOExceptionError " + e.toString());
}
It gives error:
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean
android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat,
int, java.io.OutputStream)' on a null object reference
Is there anything I missed or did it wrong?
It turns out that the image file has to be re-organized and as for Depth16 file, every pixel has 16 bits of data, so the code to convert it into a jpg file is:
Image depthimage = fromFrame.getImage();
int imwidth = depthImage.getWidth();
int imheight = depthImage.getHeight();
Image.Plane plane = depthImage.getPlanes()[0];
ShortBuffer shortDepthBuffer = plane.getBuffer().asShortBuffer();
File sdCardFile = Environment.getExternalStorageDirectory();
File file = new File(sdCardFile, "depthImage.jpg");
Bitmap disBitmap = Bitmap.createBitmap(imwidth, imheight, Bitmap.Config.RGB_565);
for (int i = 0; i < imheight; i++) {
for (int j = 0; j < imwidth; j++) {
int index = (i * imwidth + j) ;
shortDepthBuffer.position(index);
short depthSample = shortDepthBuffer.get();
short depthRange = (short) (depthSample & 0x1FFF);
byte value = (byte) depthRange ;
disBitmap.setPixel(j, i, Color.rgb(value, value, value));
}
}
Matrix matrix = new Matrix();
matrix.setRotate(90);
Bitmap rotatedBitmap = Bitmap.createBitmap(disBitmap, 0, 0, imwidth, imheight, matrix, true);
try {
FileOutputStream out = new FileOutputStream(file);
rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
MainActivity.num++;
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
I also rotate the picture to make it easier to review on mobile devices
I'm try to get a byte array from a picture stored on an android device, but the byte array size is width * heigth * 2, and I need a byte array of the size width * heigth * 3.
My problem is that I need to send a picture byte array to a matlab server that need the array in this RGB format.
Here is the code that creates a byte array of "width * height" size:
Bitmap photo = BitmapHelper.readBitmap(CameraIntentActivity.this, photoUri);
if (photo != null) {
photo = BitmapHelper.shrinkBitmap(photo, 300, rotateXDegrees);
Bitmap bm = Bitmap.createScaledBitmap(photo, 640, 480, true);
final int lnth= bm.getByteCount();
ByteBuffer dst= ByteBuffer.allocate(lnth);
bm.copyPixelsToBuffer( dst);
byte[] byteArray = dst.array();
The readBitmap method:
public static Bitmap readBitmap(Context context, Uri selectedImage) {
Bitmap bm = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
options.inScaled = false;
AssetFileDescriptor fileDescriptor = null;
try {
fileDescriptor = context.getContentResolver().openAssetFileDescriptor(selectedImage, "r");
} catch (FileNotFoundException e) {
return null;
} finally {
try {
bm = BitmapFactory.decodeFileDescriptor(
fileDescriptor.getFileDescriptor(), null, options);
fileDescriptor.close();
} catch (IOException e) {
return null;
}
}
return bm;
}
i trying to give responce as multiple images byte array to another application.
I get the vehicle images list from database and convert to byte array.
ByteArrayInputStream instream = null;
ServletOutputStream out = null ;
for(Vehicle vehicle : vehicleList)
{
byte[] imageInByte = null;
VehicleImage vehicleImage=VehicleImagePeer.doSelectFirst(c.add(VehicleImagePeer.VEHICLE_ID, getId()));
c.clear();
String path = TaxiApp.getConfigValue("IMAGE.PATH")+vehicleImage.getPath();
System.out.print(path);
BufferedImage originalImage = ImageIO.read(new File(path));
ImageIO.write(originalImage, "png", baos);
imageInByte = baos.toByteArray();
baos.close();
using this code i convert all the images to byte Array.
As Now i need to give response.
i used this code to response
out = response.getOutputStream();
response.setContentLength(imageInByte.length);
response.setCharacterEncoding(Charset.forName("UTF-8").name());
int bufferSize = response.getBufferSize();
byte[] buffer = new byte[bufferSize];
instream = new ByteArrayInputStream(imageInByte);
TaxiApp.logprintf("Total page size in bytes: %s and default response bufferSize in bytes: %s%n", new Object[]
{
Integer.valueOf(imageInByte.length), Integer.valueOf(bufferSize)
});
int length = 0;
while ((length = instream.read(buffer, 0, bufferSize)) != -1)
{
out.write(buffer, 0, length);
out.flush();
}
Here is a problem for me.
The response can send the first image byte array only.but i need to send all the image byte Array...please sort out this problem.
ImagesService imagesService = ImagesServiceFactory.getImagesService();
BlobKey bk = currentProfile.getProfileBlobKey();
Image oldImage = ImagesServiceFactory.makeImageFromBlob(bk);
Transform resize = ImagesServiceFactory.makeResize(500, 500);
Image newImage = imagesService.applyTransform(resize, oldImage);
int imageWidth = newImage.getWidth();
int imageHeight = newImage.getHeight();
This code doesn't seem to work since ImagesServiceFactory.makeImageFromBlob(bk); doesn't return a real Image. Does anyone know a workaround for this? This seems to be the expected behavior. This issue is discussed here but they don't have a solution for getting the height and width just the byte[]
Try this:
FileService fileService = FileServiceFactory.getFileService();
AppEngineFile blobFile = fileService.getBlobFile(blobKey);
FileReadChannel readChannel = fileService.openReadChannel(blobFile, false);
byte[] imageData = getBytes(Channels.newInputStream(readChannel));
Image oldImage = ImagesServiceFactory.makeImage(imageData);
// now you have the real Image
and this little snippet for reading an input stream:
public static byte[] getBytes(InputStream is) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int len;
byte[] data = new byte[10000];
while ((len = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, len);
}
buffer.flush();
return buffer.toByteArray();
}
have you tried the ImageReader Class?
try {
URL url = new URL(this.url);
InputStream in = new BufferedInputStream(url.openStream());
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int n = 0;
while (-1 != (n = in.read(buf))) {
out.write(buf, 0, n);
}
out.close();
in.close();
byte[] response = out.toByteArray();
Pixmap pixmap = new Pixmap(response, 0, response.length);
texture = new Texture(pixmap); // <- here Im getting an exception
} catch (Exception e) {
// cause=NullPointerException
// pixmap was initialized successfully
}
All the code is working in thread.
Code works great in UI thread.
Any ideas?
I think you are not allowed to work with opengl in a thread different from the one where opengl context was created.
http://code.google.com/p/libgdx/wiki/ApplicationThreading