Write 2D array of image data in file in Android - java

I have a 2D array of image data in which I did some manipulations, but image is not getting saved on path specified i.e. Environment.getExternalStorageDirectory().getPath()+File.separator+"output.png".
I did the same code for Desktop application it is working fine in core Java. I have used BufferedImage to save 2D array of image data in a file. It is working totally fine, but I was wondering why this is not working in android. I did some research on this also, I got to know that Bitmap is the alternative for BufferedImage but the image is not getting written. Here I am posting my code please help me.
This is my java code:
BufferedImage theImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < imageHeight; ++y) {
for (int x = 0; x < imageWidth; ++x) {
theImage.setRGB(x, y, imgData[x][y]);
}
}
File outputfile = new File(filename);
try {
ImageIO.write(theImage, "png", outputfile);
} catch (IOException ex) {
}
Android code that I've tried:
int i =0;
for (int y = 0; y < imageHeight; ++y) {
for (int x = 0; x < imageWidth; ++x) {
values[i] = (byte) imgData[x][y];
i++;
}
}
try {
Bitmap bmp = BitmapFactory.decodeByteArray(values, 0, values.length);
OutputStream fos=new FileOutputStream(filename);
fos.write(values);
fos.close();
fos.flush();
res = true;
}catch (java.io.IOException e) {
e.printStackTrace();
}

Have you tried to Compress Before Writing Stream ??
insert this before stream write :
bmp.compress(Bitmap.CompressFormat.PNG, 90, fos);
Or: you can Use this Method:
private void createDirectoryAndSaveFile(Bitmap imageToSave, String fileName) {
File direct = new File(Environment.getExternalStorageDirectory() + "/DirName");
if (!direct.exists()) {
File wallpaperDirectory = new File("/sdcard/DirName/");
wallpaperDirectory.mkdirs();
}
File file = new File(new File("/sdcard/DirName/"), fileName);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}

Related

How to add several barcode images to one image png? [duplicate]

This question already has answers here:
How to combine multiple PNGs into one big PNG file?
(10 answers)
Closed 2 years ago.
My case is what I need to add several barcodes (png) which I generated using Barcode4j library in one png file. I couldn't find any examples, also couldn't make up my mind to solve it. So any help will be appreciated.
Well, I generate barcodes in usual way (throug for) and collecte them in a list of bufferedImages (List). Now I need to glue this images in one.
My code:
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BitmapCanvasProvider canvas = new BitmapCanvasProvider(baos, "image/x-png", 300, BufferedImage.TYPE_BYTE_BINARY, false, 0);
List<BufferedImage> bufferedImageList = new ArrayList<>(); // list for bufferedImages
for (int i = 0; i < barcodesList.size(); i++) {
try {
Code128Bean code128 = new Code128Bean();
code128.setHeight(15f);
code128.setModuleWidth(0.3);
code128.setQuietZone(10);
code128.doQuietZone(true);
code128.generateBarcode(canvas, (String) barcodesList.get(i));
bufferedImageList.add(canvas.getBufferedImage()); // collect images of barcode in cicle
canvas.finish();
} catch (Exception e) {
e.printStackTrace();
}
}
FileOutputStream fos = new FileOutputStream(barcodePath.toString());
// to do smth to make one png from collected images
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
Well, my code which combine several barcodes looks like this
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BitmapCanvasProvider canvas = new BitmapCanvasProvider(baos, "image/x-png", 300, BufferedImage.TYPE_BYTE_BINARY, false, 0);
List<BufferedImage> bufferedImageList = new ArrayList<>(); // list for bufferedImages
int sumHeight = 0;
int sumWhide = 0;
int columns = 2;
int rows = 0;
for (int i = 0; i < barcodesList.size(); i++) {
try {
Code128Bean code128 = new Code128Bean();
code128.setHeight(15f);
code128.setModuleWidth(0.3);
code128.setQuietZone(10);
code128.doQuietZone(true);
code128.generateBarcode(canvas, (String) barcodesList.get(i));
sumHeight = sumHeight + canvas.getBufferedImage().getHeight();
sumWhide = sumWhide + canvas.getBufferedImage().getWidth();
bufferedImageList.add(canvas.getBufferedImage()); // collect images of barcode in cycle
canvas.finish();
} catch (Exception e) {
e.printStackTrace();
}
}
double dbl = barcodesList.size() / (double) columns;
rows = (int)Math.ceil(dbl);
int oneWhide = sumWhide / barcodesList.size();
int imgWhide = oneWhide * columns;
int oneHeight = sumHeight / barcodesList.size();
int imgHeight = oneHeight * rows;
BufferedImage bigImage = new BufferedImage(imgWhide, imgHeight, BufferedImage.TYPE_BYTE_BINARY);
Graphics g = bigImage.getGraphics();
int x = 0;
int y = 0;
for (BufferedImage bufferedImage : bufferedImageList) {
g.drawImage(bufferedImage, x, y, null);
x += oneWhide;
if(x >= bigImage.getWidth()){
x = 0;
y += bufferedImage.getHeight();
}
}
ImageIO.write(bigImage,"png",new File(barcodePath.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}

save image file with bitmap factory

I'm encountering an issue with bitmap factory.
I've got a method to reduce and rotate an image to show a preview in an image view, but I would like to save this with the new size.
I'm just turning around with inputfilestream and outputfilestream but don't get to save it.
Is anybody know a clear method to put my bitmap in an outpufilestream?
Thanks a lot
here's my code
#Override
protected void onResume() {
super.onResume();
File[] fileArray;
final File root;
File chemin = Environment.getExternalStorageDirectory();
String filepath = chemin + "/SmartCollecte/PARC/OUT/" + fichano + "_" + conteneur_s+"_"+cpt+".jpg";
try {
decodeFile(filepath);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}}
public void decodeFile(String filePath) {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 1024;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap b1 = BitmapFactory.decodeFile(filePath, o2);
Bitmap b = ExifUtils.rotateBitmap(filePath, b1);
FileOutputStream fos = new FileOutputStream(filePath);
b.compress(Bitmap.CompressFormat.PNG,100,fos);
fos.close();
showImg.setImageBitmap(b);
}
Have you tried doing it like this?
Assuming bitmap is bitmap you want to save.
Also, take a look at some existing system directories.
final FileOutputStream fos = new FileOutputStream(new File(filepath + "_scaled.jpg"));
try {
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
} catch (IOException e) {
// handle exception
} finally {
fos.close
}
Source
Where first parameter of Bitmap.compress() is your desired output format (see CompressFormat) and the second parameter is compression quality.
ok I found out what was missing.
had to create a new byte array to convert my bitmap to file :
String filepathcomp = Environment.getExternalStorageDirectory()+"/SmartCollecte/PARC/OUT/"+ fichano + "_" + conteneur_s+"_"+cpt+".jpg";
File f = new File(filepathcomp);
Bitmap newbitmap = b;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
newbitmap.compress(Bitmap.CompressFormat.JPEG,80,bos);
byte[] bitmapdata = bos.toByteArray();
FileOutputStream fos = new FileOutputStream(f);
fos.write(bitmapdata);
fos.flush();
fos.close();

Java android change black color in picture to tracspadence and save in file

Hi I want to rotate my image and save in file I did this :
for (int i = 0; i < 361; i++) {
Bitmap bm = RotateMyBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.znacznik_new), i);
String path = Environment.getExternalStorageDirectory().toString();
OutputStream fOut = null;
Integer counter = 0;
File file = new File(path, "ikona"+i+".jpg"); // the File to save , append increasing numeric counter to prevent files from getting overwritten.
try {
fOut = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
bm.compress(Bitmap.CompressFormat.JPEG, 85, fOut); // saving the Bitmap to a file compressed as a JPEG with 85% compression rate
try {
fOut.flush(); // Not really required
} catch (IOException e) {
e.printStackTrace();
}
try {
fOut.close(); // do not forget to close the stream
} catch (IOException e) {
e.printStackTrace();
}
try {
MediaStore.Images.Media.insertImage(getContentResolver(),file.getAbsolutePath(),file.getName(),file.getName());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static Bitmap RotateMyBitmap(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}
And I rotate image and I have files but a image have a black background and my oryginal image doesn't have a black background it have transpadence . How I can change a black color to transpadence and save in file
JPEG doesn't support transparency, all the transparent parts will turn black.
Compress the bitmap with Bitmap.CompressFormat.PNG.
bm.compress(Bitmap.CompressFormat.PNG, 100, fOut);

Creation of GIF is taking so long time in Android

I am creating a app which burst capture images and create a GIF as output. My problem is creation of GIF from the image sequence is taking so long time, whether the resolution of images are 320x240. I am using AnimatedGifEncoder class for GIF encoding. as follow this link.
My code for creation of GIF is as following
private void saveGifImage() {
FileOutputStream outStream =
String fileName = "test.gif";
try {
File file = new File(Environment.getExternalStorageDirectory() + "/gif_convertor/sample/");
if (!file.exists())
file.mkdirs();
File file1 = new File(file + File.separator +
if (file1.exists()) {
} else {
try {
// file1.mkdirs();
file1.createNewFile();
} catch (Exception e) {
}
}
outStream = new FileOutputStream(file1);
Log.d("Location", file1.getPath().toString());
outStream.write(generateGIF());
outStream.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
DialogUtils.stopProgressDisplay();
}
}
private byte[] generateGIF() {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
AnimatedGifEncoder encoder = new AnimatedGifEncoder();
encoder.start(bos);
encoder.delay = 33; // 50 means 0.5 seconds ( 100 value is equivalent to 1 seconds)
encoder.repeat = 0; // 0 means repeat forever, other n positive integer means n times repeat , -1 means no repeat
encoder.sizeSet = true; // resize allowed with true flag
encoder.width = 320;
encoder.height = 240;
File tempDir = new File(getActivity().getExternalFilesDir(null), "temp");
if (tempDir.exists()) {
for (File file : tempDir.listFiles()) {
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
encoder.addFrame(bitmap);
}
}
encoder.finish();
return bos.toByteArray();
}

Why i cannot show my byte[] image after converting it from bitmap?

I'm trying to write a method that accepts an image(Bitmap) and returns a byte[] array. finally, I try to write this byte[] array to a folder so I can see the difference, but my byte[] arraycan not displayed, and in addition, it is not scaled down! This is my method:
private byte[] changeSize(Bitmap image) {
byte[] picture;
int width = image.getWidth();
int height = image.getHeight();
int newHeight = 0, newWidth = 0;
if (width > 250 || height > 250) {
if (width > height) { //landscape-mode
newHeight = 200;
newWidth = (newHeight * width) / height;
} else { //portrait-mode
newWidth = 200;
newHeight = (newWidth * height) / width;
}
} else {
Toast.makeText(this, "Something wrong!", Toast.LENGTH_LONG).show();
}
Bitmap sizeChanged = Bitmap.createScaledBitmap(image, newWidth, newHeight, true);
//Convert bitmap to a byte array
int bytes = sizeChanged.getByteCount();
ByteBuffer bb = ByteBuffer.allocate(bytes);
sizeChanged.copyPixelsFromBuffer(bb);
picture = bb.array();
//Write to a hd
picturePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String fileName = edFile.getText().toString() + "_downscaled" + ".jpg";
File file = new File(picturePath, fileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
fos.write(picture);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
return image;
}
I tried several hours to get my byte[] array visible, but I could simply not do this. Any help or hints to show me where I derail is/are very appreciated.
This was working for me
public static Bitmap byteArraytoBitmap(byte[] bytes) {
return (BitmapFactory.decodeByteArray(bytes, 0, bytes.length));
}
public static byte[] bitmaptoByteArray(Bitmap bmp) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream); //PNG format is lossless and will ignore the quality setting!
byte[] byteArray = stream.toByteArray();
return byteArray;
}
public static Bitmap bitmapFromFile(File file) {
//returns null if could not decode
return BitmapFactory.decodeFile(file.getPath());
}
public static boolean saveImage(Bitmap image, String filePath) {
LogInfo(TAG, "Saving image to: " + filePath);
File file = new File(filePath);
File fileDirectory = new File(file.getParent());
LogInfo(TAG, fileDirectory.getPath());
if (!fileDirectory.exists()) {
if (!fileDirectory.mkdirs()) {
Log.e(TAG, "ERROR CREATING DIRECTORIES");
return false;
}
}
try {
file.createNewFile();
FileOutputStream fo = new FileOutputStream(file);
fo.write(bitmaptoByteArray(image));
fo.flush();
fo.close();
return true;
}
catch (Exception e) {
e.printStackTrace();
return false;
}
}

Categories