I have a layout in an Android activity, I convert it as an image and then share it on different social networks.
The things is that the quality is not good at all, I have artifacts on the image, and the quality depend of the size of the screen.
Is there any way to improve the quality ? I can't store the complete layout image as a static image in the application directory, I need it to be generated on the go.
Here is code I use to transform the layout into a PNG.
Bitmap bitmap = null;
try {
bitmap = Bitmap.createBitmap(dashboardView.getWidth(),
dashboardView.getHeight(), Bitmap.Config.ARGB_4444);
dashboardView.draw(new Canvas(bitmap));
} catch (Exception e) {
// Logger.e(e.toString());
}
FileOutputStream fileOutputStream = null;
File path = Environment
.getExternalStorageDirectory();
File file = new File(path, "wayzupDashboard" + ".png");
try {
fileOutputStream = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
bitmap.compress(CompressFormat.PNG, 100, bos);
try {
bos.flush();
bos.close();
fileOutputStream.flush();
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
Edit: My bad, I left ARGB_4444, the fact is I made a lot of test before posting the question on SO, I just forgot to put ARGB_8888 in. Still the image quality is bad on Android phone with tiny screen. If only I could tell to always use HDPI drawable while capturing the layout.
ARGB_4444 means that you have only 4 bits per channel (a really poor quality).
Use ARGB_8888.
you are using Bitmap.Config.ARGB_4444. I suggest you to use ARGB_8888, like Google tells us
ARGB_4444 This field was deprecated in API level . Because of the
poor quality of this configuration, it is advised to use ARGB_8888
instead.
Related
I've managed to make a LineFollower program; added the feature of "memorizing" the path the robot just followed.
The next step is to draw that path and save the image file in the brick and read it in the PC with the NxjBrowse.
I thought I'd try using the classic java method, with BufferedImage and saving with ImageIO, but it didn't work and it kept giving me Java Heap Space:
My previous question
After that, I've made some research and found that there's a class called javax.microedition.lcdui.Image, so I've created an Image object and used GetGraphics and tried to draw on it; and save it using FileOutputStream, here's my code:
Image img = Image.createImage(300, 300);
Graphics g = img.getGraphics();
g.drawLine(0, 0, 100, 200);
File monFichier = new File("Image2.png");
FileOutputStream fOut = null;
try {
fOut = new FileOutputStream(monFichier);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] b = img.getData();
try {
fOut.write(b);
fOut.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The problem is that it writes on the file which is not recognized as an image, when I connect to my PC; I can't open the created file (checked the size, not empty).
I don't know if the saving is wrong or the method i'm using to draw is wrong.
Short version of the question: How to draw lines with Lejos and save the resultat as an image file?
Thank you.
UPDATE:
I used an ImageOutputStream instead of FileOutputStream; and now it's giving me "Java Heap Space" error; after it got stuck in "linking" for a while.
Java Heap Space
Java.lang.OutOfMemoryError
Image.getData() is an access to the underlying DataBuffer and not a valid PNG or BMP image.
Try ImageIO.write(img, "png", outputfile).
I have a gif image and I would like to be able to detect whether the gif is an animated gif or not using JAVA. This question is about detection rather than displaying the gif.
I see that MIME type of animated gif isn't different of static gif.
How I can do it?
You need an ImageReader. if size is 1 its not animated, everything above is animated.
Check this out:
public Snippet() {
File f = new File("test.gif");
ImageReader is = ImageIO.getImageReadersBySuffix("GIF").next();
ImageInputStream iis;
try {
iis = ImageIO.createImageInputStream(f);
is.setInput(iis);
int images= is.getNumImages(true);
} catch (IOException e) {
e.printStackTrace();
}
}
I've been searching for some solutions from the internet yet I still haven't found an answer to my problem.
I've been working or doing a program that would get an image file from my PC then will be edited using Java Graphics to add some text/object/etc. After that, Java ImageIO will save the newly modified image.
So far, I was able to do it nicely but I got a problem about the size of the image. The original image and the modified image didn't have the same size.
The original is a 2x3inches-image while the modified one which supposedly have 2x3inches too sadly got 8x14inches. So, it has gone BIGGER than the original one.
What is the solution/code that would give me an output of 2x3inches-image which will still have a 'nice quality'?
UPDATE:
So, here's the code I used.
public Picture(String filename) {
try {
File file = new File("originalpic.jpg");
image = ImageIO.read(file);
width = image.getWidth();
}
catch (IOException e) {
throw new RuntimeException("Could not open file: " + filename);
}
}
private void write(int id) {
try {
ImageIO.write(image, "jpg", new File("newpic.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
}
2nd UPDATE:
I now know what's the problem of the new image. As I check it from Photoshop, It has a different image resolution compared to the original one. The original has a 300 pixels/inch while the new image has a 72 pixels/inch resolution.
How will I be able to change the resolution using Java?
To set the image resolution (of the JFIF segment), you can probably use the IIOMetatada for JPEG.
Something along the lines of:
public class MetadataTest {
public static void main(String[] args) throws IOException {
BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_3BYTE_BGR);
ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next();
writer.setOutput(ImageIO.createImageOutputStream(new File("foo.jpg")));
ImageWriteParam param = writer.getDefaultWriteParam();
IIOMetadata metadata = writer.getDefaultImageMetadata(ImageTypeSpecifier.createFromRenderedImage(image), param);
IIOMetadataNode root = (IIOMetadataNode) metadata.getAsTree(metadata.getNativeMetadataFormatName());
IIOMetadataNode jfif = (IIOMetadataNode) root.getElementsByTagName("app0JFIF").item(0);
jfif.setAttribute("resUnits", "1");
jfif.setAttribute("Xdensity", "300");
jfif.setAttribute("Ydensity", "300");
metadata.mergeTree(metadata.getNativeMetadataFormatName(), root);
writer.write(null, new IIOImage(image, null, metadata), param);
}
}
Note: this code should not be used verbatim, but adding iteration, error handling, stream closing etc, clutters the example too much.
See JPEG Image Metadata DTD for documentation on the metadata format, and what options you can control.
Im trying to add a image from a URL address to my pdf. The code is:
Image image=Image.getInstance("http://www.google.com/intl/en_ALL/images/logos/images_logo_lg.gif");
image.scaleToFit((float)200.0, (float)49.0);
paragraph.add(image);
But it does not work. What can be wrong?
This is a known issue when loading .gif from a remote location with iText.
A fix for this would be to download the .gif with Java (not via the getInstance method of iText's Image class) and to use the downloaded bytes in the getInstance method of the Image class.
Edit:
I went ahead and fixed remote gif loading in iText, it is included from iText 5.4.1 and later.
Adding Image into Itext PDF is not possible through URL .
Only way to add image in PDF is download all images in to local directory and apply below code
String photoPath = Environment.getExternalStorageDirectory() + "/abc.png";
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
final Bitmap b = BitmapFactory.decodeFile(photoPath, options);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Bitmap.createScaledBitmap(b, 10, 10, false);
b.compress(Bitmap.CompressFormat.PNG, 30, stream);
Image img = null;
byte[] byteArray = stream.toByteArray();
try {
img = Image.getInstance(byteArray);
} catch (BadElementException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
The way you have used to add images to IText PDF is the way that is used for adding local files, not URLs.
For URLs, this way will solve the problem.
String imageUrl = "http://www.google.com/intl/en_ALL/"
+ "images/logos/images_logo_lg.gif";
Image image = Image.getInstance(new URL(imageUrl));
You may then proceed to add this image to some previously open document, using document.add(image).
For further reference, please visit the [Java IText: Image docs].
I have a JSP that allows the user to export some data. You can choose differents formats (excel, csv). Also, with the excel are exported the charts corresponding to the data (pie chart, line chart and bar chart) The user want to export the charts in a unique jpg file.
What I did is (all in Java):
Generate the charts using JFreeChart
Convert the chart into a JPG image using: ChartUtilities.saveChartAsJPEG
Then I retrieve theimage bytes:
The code:
InputStream is = null;
try {
is = new FileInputStream(image);
}catch (FileNotFoundException e) {
e.printStackTrace();
}
byte[] bytes = null;
try {
bytes = IOUtils.toByteArray(is);
}catch (IOException e) {
e.printStackTrace();
}
This is working well, I have the bytes for each chart. Then I put the bytes for each chart in a byte array:
byte[] imageBytes = getImageAsBytes(chart1,chart2,chart3);
res.setContentType("image/jpg");
res.setHeader("Content-Disposition", "attachment; filename=" + "MyCharts" + ".jpg");
res.setContentLength(imageBytes.length);
try{
OutputStream output = res.getOutputStream();
output.write(imageBytes);
output.flush();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
The problem is: when I open the JPG, only one image is displayed. I tested the export for each chart and works well, but when I put all the chart bytes, is only displayed one image (always the first in the imageBytes array)
I don't know if I have to create some kind of canvas, or just is not possible put 3 images or more in the same JPG by this way.
The JPG file format isn't going to let you get away with that. My suggestion would be to create a new BufferedImage with a large enough canvas to contain all three images, render your three images onto it at staggered Y axis offsets, and then dump it out to JPG with ImageIO.