I'm using this code for image compression before uploading the images :
public File saveBitmapToFile(File file) {
try {
// BitmapFactory options to downsize the image
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
o.inSampleSize = 6;
// factor of downsizing the image
FileInputStream inputStream = new FileInputStream(file);
//Bitmap selectedBitmap = null;
BitmapFactory.decodeStream(inputStream, null, o);
inputStream.close();
// The new size we want to scale to
final int REQUIRED_SIZE = 75;
// Find the correct scale value. It should be the power of 2.
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_SIZE &&
o.outHeight / scale / 2 >= REQUIRED_SIZE) {
scale *= 2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
inputStream = new FileInputStream(file);
Bitmap selectedBitmap = BitmapFactory.decodeStream(inputStream, null, o2);
inputStream.close();
FileOutputStream outputStream = new FileOutputStream(file);
selectedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
return file;
} catch (Exception e) {
return null;
}
}
The problem is the original image will be affected and get resized.
How to compress images without overwriting and losing the original one?
Update 1 :
I changed the last part of the code to this but still doesn't work.
now the image wouldn't get resized
File new_file =new File("/storage/emulated/0/DCIM/Screenshots/tmp.png");
try
{
new_file.createNewFile();
}
catch (IOException e)
{
e.printStackTrace();
}
Log.d("Create File", "File exists?"+new_file.exists());
FileOutputStream outputStream = new FileOutputStream(new_file);
selectedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
return file;
Update 2 :
I've changed the code to this so the problem is partly solved. Now I can have an original quality of each image in a file named tmp"+new Date()+".png but the original file still will be overwritten.
File new_file =new File(String.valueOf("/storage/emulated/0/DCIM/Screenshots/tmp"+new Date()+".png"));
try
{
new_file.createNewFile();
FileOutputStream outputStream = new FileOutputStream(new_file, true);
selectedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
}
catch (IOException e)
{
e.printStackTrace();
}
Log.d("Create File", "File exists?"+new_file.exists());
FileOutputStream outputStream = new FileOutputStream(file);
selectedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
Create a new File and make the FileOutputStream write to it, rather than writing to the original.
New Answer
Your case is quite unique, what if you try this:
Rather than directly using the Bitmap from InputStream, try use it's copy().
That way, the one that you compress will be the copy of the Bitmap. And you can compress that in your new FileOutputStream without modifying the original file.
And remove the second compression. Just dont do anything with your original file.
Related
I am trying to capture one of my layout but getting black border in screenshot like below. How can I remove it ?
My code for taking screenshot is like below
private void takeScreenshot() {
Date now = new Date();
android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);
try {
// image naming and path to include sd card appending name you choose for file
String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg";
// create bitmap screen capture
View v1= findViewById(R.id.quoteViewPager);
v1.getRootView();
v1.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
File imageFile = new File(mPath);
FileOutputStream outputStream = new FileOutputStream(imageFile);
int quality = 100;
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
outputStream.flush();
outputStream.close();
openScreenshot(imageFile);
} catch (Throwable e) {
// Several error may come out with file handling or OOM
e.printStackTrace();
}
}
Thanks
Actually, I didn't get your code,
View v1= findViewById(R.id.quoteViewPager);
v1.getRootView();
it should be :
v1 = v1.getRootView();
Hope it will help you :)
Tried to use several libraries like ZXing, ZBar and their forks but didn't find way to scan barcode not from camera but from file.
Can someone point me to right direction? Preferably I'm looking into ZXing: how to scan image from file (not from camera).
Please.
In the end I've found solution. Code is (originated from here):
import com.google.zxing.*;
public static String scanQRImage(Bitmap bMap) {
String contents = null;
int[] intArray = new int[bMap.getWidth()*bMap.getHeight()];
//copy pixel data from the Bitmap into the 'intArray' array
bMap.getPixels(intArray, 0, bMap.getWidth(), 0, 0, bMap.getWidth(), bMap.getHeight());
LuminanceSource source = new RGBLuminanceSource(bMap.getWidth(), bMap.getHeight(), intArray);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Reader reader = new MultiFormatReader();
try {
Result result = reader.decode(bitmap);
contents = result.getText();
}
catch (Exception e) {
Log.e("QrTest", "Error decoding barcode", e);
}
return contents;
}
Gradle referencing as:
dependencies {
compile 'com.google.zxing:core:3.2.1'
}
Usage:
InputStream is = new BufferedInputStream(new FileInputStream(file));
Bitmap bitmap = BitmapFactory.decodeStream(is);
String decoded=scanQRImage(bitmap);
Log.i("QrTest", "Decoded string="+decoded);
I have a pdf file (obtained from a byte[] generated by iText) I need to send to a signature hardware.
Due some incompatibility with the java printer driver I can't send the PDF directly, so i need to convert it to images before. I've succeed converting each PDF page to a jpg file, but customer does not like solution cause signatures are not in all the document, only in individual pages.
As I've not found any free library, I decided to make it in four steps:
STEP1: generate PDF with itext and persist it.
FileOutputStream fos = new FileOutputStream("tempFile.pdf");
fos.write(myByteArray);
fos.close();
fos.flush();
STEP 2: convert from PDF multipaged to List<java.awt.Image>
List<Image> images = null;
Ghostscript.getInstance(); // create gs instance
PDFDocument lDocument = new PDFDocument();
lDocument.load(new File("tempFile.pdf"));
SimpleRenderer renderer = new SimpleRenderer();
renderer.setResolution(300);
try
{
images = renderer.render(lDocument);
}
catch (RendererException | DocumentException e)
{
e.printStackTrace();
}
Step 3: Now I iterate over List<java.awt.Image> to convert to an individual TIFF's.
int filename = 1;
TIFFEncodeParam params = new TIFFEncodeParam();
Iterator<Image> imageIterator = images.iterator();
while (imageIterator.hasNext()) {
BufferedImage image = (BufferedImage) imageIterator.next();
FileOutputStream os = new FileOutputStream(/*outputDir + */ filename + ".tif");
JAI.create("encode", image , os, "TIFF", params);
filename ++;
}
STEP 4: create multipaged TIFF from various individual TIFF files
BufferedImage image[] = new BufferedImage[paginas];
for (int i = 0; i < paginas; i++) {
SeekableStream ss = new FileSeekableStream((i + 1) + ".tif");
ImageDecoder decoder = ImageCodec.createImageDecoder("tiff", ss, null);
PlanarImage pi = new NullOpImage(decoder.decodeAsRenderedImage(0),null,null,OpImage.OP_IO_BOUND);
image[i] = pi.getAsBufferedImage();
ss.close();
}
TIFFEncodeParam params = new TIFFEncodeParam();
params.setCompression(TIFFEncodeParam.COMPRESSION_DEFLATE);
OutputStream out = new FileOutputStream(nombre +".tif");
ImageEncoder encoder = ImageCodec.createImageEncoder("tiff", out, params);
List <BufferedImage>list = new ArrayList<BufferedImage>(image.length);
for (int i = 1; i < image.length; i++) {
list.add(image[i]);
}
params.setExtraImages(list.iterator());
encoder.encode(image[0]);
out.close();
System.out.println("Done.");
DONE. Hope that helps for someone else with same problem.
I had same issue a while ago. I got lot of help from here:
Multiple page tif
Allso check:
JAI (Java Advance Image)
Here is the conde snippet to convert pdf pages to png images (using org.apache.pdfbox library):
PDDocument document = null;
document = PDDocument.load(pdf1);
int pageNum = document.getNumberOfPages();
PDFImageWriter writer = new PDFImageWriter();
String filename = pdf1.getPath() + "-";
filename = filename.replace(".pdf", "");
writer.writeImage(document, "png", "", 1, Integer.MAX_VALUE, filename);
document.close();
And after that i converted each PNG image to TIFF and then from multiple TIFF images to single multi paged TIFF.
I am trying to merge two TIFF images which are in form of FileInputStream into a single Tiff image. Although the image is getting merged the output file is coming up as Black. While comparing the original image and the converted image I could see that the bit depth of the converted image changes to 1. Could anybody provide a solution to this?
The code that I am using is:
public class MergerTiffUsingBuffer {
public static void main(String[] args) {
File imageFile1 = new File("D:/Software/pdfbox-1.3.1.jar/tiff/FLAG_T24.TIF");
File imageFile2 = new File("D:/Software/pdfbox-1.3.1.jar/tiff/CCITT_3.TIF");
try {
FileInputStream fis1 = new FileInputStream(imageFile1);
FileInputStream fis2 = new FileInputStream(imageFile2);
List<BufferedImage> bufferedImages=new ArrayList<>();
List<FileInputStream> inputStreams=new ArrayList<>();
inputStreams.add(fis1);
inputStreams.add(fis2);
Iterator<?> readers = ImageIO.getImageReadersByFormatName("tiff");
ImageReader reader = (ImageReader) readers.next();
for(FileInputStream inputStream:inputStreams){
ImageInputStream iis = ImageIO.createImageInputStream(inputStream);
reader.setInput(iis);
ImageReadParam param = reader.getDefaultReadParam();
Image image = reader.read(0, param);
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
OutputStream out = new FileOutputStream("D:/Software/pdfbox-1.3.1.jar/tiff/MergedTiff.TIF");
BufferedImage binarized = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(),BufferedImage.TYPE_BYTE_BINARY);
ImageIO.write(binarized, "tiff", out);
bufferedImages.add(bufferedImage);
}
System.out.println(bufferedImages.size());
} catch (IOException e2) {
e2.printStackTrace();
}
}
}
You seem to be a little confused about how to copy image data. Simply creating a new, blank image, by passing the dimensions of another image, will not copy it... So a fully black image is what I would expect after running your code.
Replace your for loop with something like this:
for (FileInputStream inputStream : inputStreams) {
ImageInputStream iis = ImageIO.createImageInputStream(inputStream);
reader.setInput(iis);
BufferedImage image = reader.read(0, null); // a) BufferedImage is returned! b) null param is fine!
BufferedImage binarized = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
// The following 7 lines is the important part you were missing:
Graphics2D g = binarized.createGraphics();
try {
g.drawImage(image, 0, 0, null);
}
finally {
g.dispose();
}
OutputStream out = new FileOutputStream("D:/Software/pdfbox-1.3.1.jar/tiff/MergedTiff.TIF");
ImageIO.write(binarized, "tiff", out); // You probably want to check return value (true/false)!
bufferedImages.add(image);
}
I'm getting heap space error/ out of memory exception.
I'm trying to generate a PDF using iText and converting the PDF to jpg image using aspose api. The PDF which is being generated is of 3 pages, I'm converting that PDF to image page by page and stitching them together into one jpg image. This code is working fine in my local development machine, but getting exception when move to test server.
The code which I'm using for this is:
public void silSignedPDF(AgreementBean agBean,String sourceTemplatePDFURL, Hashtable<String, String> val, String destinationPDFPath) throws IOException, DocumentException, SQLException{
String methodName = "silSignedPDF";
LogTracer.writeDebugLog(className, methodName, "Start");
String serverPath = System.getProperty("jboss.server.home.dir");
String sourceTemplatePDFURL1 = serverPath+AppConstants.PDL_Agreement_Template +"/Online_Installment_Agreement.pdf";
System.out.println("sourceTemplatePDFURL1 "+sourceTemplatePDFURL1);
File f = new File(sourceTemplatePDFURL1);
InputStream sourceTemplatePDFUrlStream = new BufferedInputStream(new FileInputStream(f));
File destinationFile = new File(destinationPDFPath+"/"+agBean.getDealNbr()+".pdf");
PdfReader reader = new PdfReader(sourceTemplatePDFUrlStream);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(
destinationFile));
AcroFields form = stamper.getAcroFields();
Enumeration enumeration = val.keys();
// iterate through Hashtable val keys Enumeration
while (enumeration.hasMoreElements()) {
String nextElement = (String) enumeration.nextElement();
String nextElementValue = (String) val.get(nextElement);
form.setField(nextElement, nextElementValue);
}
stamper.setFormFlattening(true);
stamper.close();
PdfConverter pdf = new PdfConverter();
pdf.bindPdf(destinationPDFPath+"/"+agBean.getDealNbr()+".pdf");
try {
pdf.doConvert();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//set start and end pages
pdf.setStartPage(1);
pdf.setEndPage(1);
//initialize conversion process
//convert pages to images
String suffix = ".jpg";
int imageCount = 1;
while (pdf.hasNextImage())
{
try {
pdf.getNextImage(destinationPDFPath+"/"+agBean.getDealNbr()+"_"+imageCount + suffix,ImageType.JPEG);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
imageCount++;
}
/* PDFImages pdfDoc = new PDFImages (destinationPDFPath+"/"+agBean.getDealNbr()+".pdf", null);
for (int count = 0; count < pdfDoc.getPageCount(); ++count)
{
pdfDoc.savePageAsJPEG(count,destinationPDFPath+"/"+agBean.getDealNbr()+"_"+count + ".png", 150, 0.8f);
}*/
File file1 = new File(destinationPDFPath+"/"+agBean.getDealNbr()+"_1" + ".jpg");
File file2 = new File(destinationPDFPath+"/"+agBean.getDealNbr()+"_2" + ".jpg");
File file3 = new File(destinationPDFPath+"/"+agBean.getDealNbr()+"_3" + ".jpg");
BufferedImage img1 = ImageIO.read(file1);
BufferedImage img2 = ImageIO.read(file2);
BufferedImage img3 = ImageIO.read(file3);
int widthImg1 = img1.getWidth();
int heightImg1 = img1.getHeight();
int heightImg2 = img2.getHeight();
int heightImg3 = img3.getHeight();
BufferedImage img = new BufferedImage(
widthImg1,
heightImg1+heightImg2+heightImg3,
BufferedImage.TYPE_INT_RGB);
img.createGraphics().drawImage(img1, 0, 0, null);
img.createGraphics().drawImage(img2, 0, heightImg1, null);
img.createGraphics().drawImage(img3, 0, heightImg1+heightImg2, null);
File final_image = new File(destinationPDFPath+"/"+agBean.getDealNbr() + ".jpg");
ImageIO.write(img, "png", final_image);
file1.delete();
file2.delete();
file3.delete();
LogTracer.writeDebugLog(className, methodName, "End");
}
Heap size should be changed for your JVM, but dont change it to any random number. Heap size should be modified based on the memory that is used by your system. You can check this for further specification.
Page to Image conversion using Aspose.Pdf required more memory than the default. Run the program with at least 512 MB memory (-Xmx512m).