(Android Studio) How to save bitmap to Internal Storage? - java

Im trying to save my bitmap file as to png to my Internal Storage
How can i do it?
My code to generate QR Code :-
public void createQRCode(String qrCodeData, String charset, Map hintMap, int qrCodeheight, int qrCodewidth) {
Bitmap bitmap = null;
try {
//generating qr code in bitmatrix type
BitMatrix matrix = new MultiFormatWriter().encode(new String(qrCodeData.getBytes(charset), charset), BarcodeFormat.QR_CODE, qrCodewidth, qrCodeheight, hintMap);
//converting bitmatrix to bitmap
int width = matrix.getWidth();
int height = matrix.getHeight();
int[] pixels = new int[width * height];
// All are 0, or black, by default
for (int y = 0; y < height; y++) {
int offset = y * width;
for (int x = 0; x < width; x++) {
pixels[offset + x] = matrix.get(x, y) ? BLACK : WHITE;
}
}
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
qrImageView.setImageBitmap(bitmap);
} catch (Exception er) {
Log.e("QrGenerate", er.getMessage());
}
}
I want to save the generated QR code bitmap to my Internal Storage for example say in DCIM folder i want make a new folder "QR CODES" then i want to save my bitmap as "QRCode1.png"
How can i do this?
i have tried many tutorials and none of them seem to work for me or i am doing it wrong maybe
PS
i have already added the write permission to my AndroidManifest file

Try doing this and then use the data to save it in your local device.
saveImageBitmap(Bitmap bitmap){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 20, baos);
byte[] data = baos.toByteArray();
//do whatever you want to save this bitmap file
}
Hope that'll help you out! This will transform the bitmap into .jpg format and then save it in your file.

Related

I get larger sizes after cropping the image

I have never worked with pictures in java and I am a beginner in this.
I need to make a function that will crop the images according to a certain ratio of width and height in the middle of the image.
Through REST Api I receive a MultipartFile which I pass to the image cropping function. I forward the image using file.getBytes().
Here is how I wrote the code for image crop function:
public static byte[] cropImage(byte[] data) {
ByteArrayInputStream bais = new ByteArrayInputStream(data);
try {
BufferedImage img = ImageIO.read(bais);
int width = img.getWidth();
int height = img.getHeight();
float aspectRatio = (float) 275 / (float) 160;
int destWidth;
int destHeight;
int startX;
int startY;
if(width/height > aspectRatio) {
destHeight = height;
destWidth = Math.round(aspectRatio * height);
startX = Math.round(( width - destWidth ) / 2);
startY = 0;
} else if (width/height < aspectRatio) {
destWidth = width;
destHeight = Math.round(width / aspectRatio);
startX = 0;
startY = Math.round((height - destHeight) / 2);
} else {
destWidth = width;
destHeight = height;
startX = 0;
startY = 0;
}
BufferedImage dst = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_ARGB);
dst.getGraphics().drawImage(img, 0, 0, destWidth, destHeight, startX, startY, startX + destWidth, startY + destHeight, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(dst, "png", baos);
return baos.toByteArray();
} catch (IOException e) {
throw new RuntimeException("IOException in scale");
}
}
But when I crop the image the result is an image with a much larger size than the received image. I need help on how to solve this problem.
EDIT:
According to this answer, the size increases on this part of the code:
ImageIO.read (bais)
Is there any other way to convert an image from byte array to buffered image but keep the size of the original image?
I don’t know why, but the problem was in part ImageIO.write(dst, "png", baos);
I was trying with different types of images (png, jpg, jpeg) and only with png did it reduce my image size. While in the situation when I changed to jpeg it reduced the size in all images.

How to find out that the Barcode has been scanned?

I have this method to generate a Barcode bitmap:
public static Bitmap encodeToQrCode(String text, int width, int height) {
QRCodeWriter writer = new QRCodeWriter();
BitMatrix matrix = null;
try {
matrix = writer.encode(text, BarcodeFormat.QR_CODE, 400, 400);
} catch (WriterException ex) {
ex.printStackTrace();
}
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height - 1; y++) {
bmp.setPixel(x, y, matrix.get(x, y) ? Color.BLACK : Color.WHITE);
}
}
return bmp;
}
Is there any way to find out that the Barcode has been scanned? I'm using zxing.
If I understand you correctly you're looking for a way to
Create a bitmap that contains a QR code
Display that bitmap on your device
Detect when a different device that doesn't use your software scans that code
This is not possible. The QR code bitmap is just that: A bitmap your app displays. And a barcode scanner app simply takes a photo of your display and tries to find patterns in that bitmap.

Android: How to pass Bitmap Images to ArrayList<Bitmap> and retrieve it

"Base64Parts" is a string that has been split to equal parts, and I am trying to generate a QR code for each string and place it in a arraylist so that i can retrieve it and generate a GIF. Am I adding the bitmap images to the arraylist in the correct way? Because i can only retrieve "bmp_images.get(0)". Not others (eg-bmp_images.get(1)). My code is given below.
//Declaring QR code generator
QRCodeWriter writer = new QRCodeWriter();
//Declaring Array
ArrayList<Bitmap> bmp_images = new ArrayList<Bitmap>();
for (int i = 0; i < numberOfPartsSplit; i++){
try {
Hashtable<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<EncodeHintType, ErrorCorrectionLevel>();
hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
BitMatrix bitMatrix = writer.encode(Base64Parts.get(i), BarcodeFormat.QR_CODE, 512, 512, hintMap);
int width = bitMatrix.getWidth();
int height = bitMatrix.getHeight();
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
bmp.setPixel(x, y, bitMatrix.get(x, y) ? Color.BLACK : Color.WHITE);
}
}
bmp_images.add(i,bmp); //the code added for arraylist of images
((ImageView) findViewById(R.id.image_holder)).setImageBitmap(bmp_images.get(0)); //use different values
} catch (WriterException e) {
e.printStackTrace();
}
((ImageView) findViewById(R.id.image_holder)).setImageBitmap(bmp_images.get(0));
paste this line outside for loop. Once all iteration done, set the needed index to get that particular value.

Creating PNG file from int Array of RGB data

I am getting the int array from png image how I will convert this to bufferdimage or creating new PNG file ?
int[] pixel = new int[w1*h1];
int i = 0;
for (int xx = 0; xx < h1; xx++) {
for (int yy = 0; yy < w1; yy++) {
pixel[i] = img.getRGB(yy, xx);
i++;
}
}
If you have an array of integers which are packed RGB values, this is the java code to save it to a file:
int width = 100;
int height = 100;
int[] rgbs = buildRaster(width, height);
DataBuffer rgbData = new DataBufferInt(rgbs, rgbs.length);
WritableRaster raster = Raster.createPackedRaster(rgbData, width, height, width,
new int[]{0xff0000, 0xff00, 0xff},
null);
ColorModel colorModel = new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
BufferedImage img = new BufferedImage(colorModel, raster, false, null);
String fname = "/tmp/whatI.png";
ImageIO.write(img, "png", new File(fname));
System.out.println("wrote to "+fname);
The reason for the arrays 0xff0000, 0xff00, 0xff is that the RGB bytes are packed with blue in the least significant byte. If you pack your ints different, alter that array.
You can rebuild the image manually, this is however a pretty expensive operation.
BufferedImage image = new BufferedImage(64, 64, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
for(int i = 0; i < pixels.size(); i++)
{
g.setColor(new java.awt.Color(pixels.get(i).getRed(), pixels.get(i).getGreen(), pixels.get(i).getBlue()));
g.fillRect(pixels.get(i).getxPos(), pixels.get(i).getyPos(), 1, 1);
}
try
{
ImageIO.write(image, "PNG", new File("imageName.png"))
}
catch(IOException error)
{
error.printStackTrace();
}
I formatted your image array into an object, this is personal preference tho (of course you could us an int array with this model as well). Keep in mind that you can always add the alpha to there as well.
Try the ImageIO class, which can take a byte array representing pixel data to build an image object and then writing it out in a particular format.
try {
BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(yourBytes));
ImageIO.write(bufferedImage, "png", new File("out.png"));
} catch (IOException e) {
e.printStackTrace();
}

Generate QR Code directly into ImageView?

I am generating a QR code with ZXing library in an Android app.
Instead of directly saving it into a file, I want it to go into an ImageView.
Here is my code:
String WIFIQRCODE = "";
String SSID = etSSID.getText().toString();
String PASS = etPASS.getText().toString();
String PASSTYPE = sTYPE.getSelectedItem().toString();
WIFIQRCODE = "WIFI:T:"+PASSTYPE+";S:"+SSID+";P:"+PASS;
//Inform the user the button1 has been clicked
QRCodeWriter writer = new QRCodeWriter();
BitMatrix bitMatrix = null;
try {
bitMatrix = writer.encode(WIFIQRCODE, BarcodeFormat.QR_CODE, 300, 300);
File file = new File(context.getFilesDir(), "/sdcard/Images/"+SSID+".png");
MatrixToImageWriter.writeToFile(bitMatrix, "png", file);
} catch (WriterException e){
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
How to modify it, so that it puts it into an ImageView instead of a file?
you will need to get Bitmap from BitMatrix to set directly image in ImageView do it as:
int height = bitMatrix.getHeight();
int width = bitMatrix.getWidth();
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
for (int x = 0; x < width; x++){
for (int y = 0; y < height; y++){
bmp.setPixel(x, y, bitMatrix.get(x,y) ? Color.BLACK : Color.WHITE);
}
}
ImageView qr_image = (ImageView) findViewById(R.id.qrimage);
qr_image.setImageBitmap(bmp);
for more detail you can see Generating QR Codes with ZXing for getting Bitmap from bitMatrix
simple way
public static Bitmap createQRImage(final String url, final int width, final int height) throws WriterException {
final BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, width, height, Collections.singletonMap(EncodeHintType.CHARACTER_SET, "utf-8"));
return Bitmap.createBitmap(IntStream.range(0, height).flatMap(h -> IntStream.range(0, width).map(w -> bitMatrix.get(w, h) ? Color.BLACK : Color.WHITE)).toArray(),
width, height, Bitmap.Config.ARGB_8888);
}
or
public static Bitmap createQRImage2(final String url, final int width, final int height) throws WriterException {
final BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, width, height, Collections.singletonMap(EncodeHintType.CHARACTER_SET, "utf-8"));
return Bitmap.createBitmap(IntStream.range(0, height * width).map(s -> bitMatrix.get(s % width, s / width) ? Color.BLACK : Color.WHITE).toArray(),
width, height, Bitmap.Config.ARGB_8888);
}
or, because Stream.toArray() allocate the output array dynamically if size unknown, which may cause memory allocation frequently if the array size too large
public static Bitmap createQRImage3(final String url, final int width, final int height) throws WriterException {
final BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, width, height, Collections.singletonMap(EncodeHintType.CHARACTER_SET, "utf-8"));
return Bitmap.createBitmap(IntStream.range(0, height)
.flatMap(h -> IntStream.range(0, width).map(w -> bitMatrix.get(w, h) ? Color.BLACK : Color.WHITE))
.collect(() -> IntBuffer.allocate(width * height), IntBuffer::put, IntBuffer::put)
.array(),
width, height, Bitmap.Config.ARGB_8888);
}
As appose to that,
get the directory to the image file then feed it in to:
Bitmap imageBitmap = BitmapFactory.decodeFile(path);
then its simple as
myImageView.setImageBitmap(imageBitmap);

Categories

Resources