How to display online images in j2me? - java

I know how to display local images in J2me. How can I display an online image? The following code (the image URL below is just for demo purposes) does not yield anything.
Image logo = Image.createImage("http://whatever.com/img/whatever.png");
Thanks

You need to load the image manually via a HttpConnection
Use this method to load the image:
public Image loadImage(String url) throws IOException {
HttpConnection hpc = null;
DataInputStream dis = null;
try {
hpc = (HttpConnection) Connector.open(url);
int length = (int) hpc.getLength();
byte[] data = new byte[length];
dis = new DataInputStream(hpc.openInputStream());
dis.readFully(data);
return Image.createImage(data, 0, data.length);
} finally {
if (hpc != null)
hpc.close();
if (dis != null)
dis.close();
}
}
See also this tutorial

Your first port of call for questions like this should be the MIDP 2.0 Javadocs.
There you will see that createImage has an overload which accepts an InputStream; this will do what you need.
Alternatively, you can download the entire image into a byte array and use yet another alternative form of createImage.

Related

How to load 1000+ images in jtable without java.lang.OutOfMemoryError: Java heap space exception

I am developing a swing application where i am displaying profile information along with their photo, after loading about 120 photos i get the exception
java.lang.OutOfMemoryError: Java heap space
I need to display around 1000+ profile informations.
This is how i load my images onto the jtable
try{
byte[] imageAsByteArray = getImageAsByteArray("E:\\Project\\WinPak\\Database\\UserImage\\"+employee.getLink3().trim()+"-1.jpg");
if(imageAsByteArray != null)
{
InputStream imageInputStream =new ByteArrayInputStream(imageAsByteArray);
Image img = ImageIO.read(imageInputStream);
ImageIcon imgIcon = new ImageIcon(img.getScaledInstance(100,100,Image.SCALE_AREA_AVERAGING));
data[index][10] =imgIcon; // data is of type object which i use to populate the jtable
imageInputStream.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
public byte[] getImageAsByteArray(String url)
{
try
{
InputStream is = new BufferedInputStream(new FileInputStream(url));
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
is.close();
return buffer.toByteArray();
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
How do i overcome this problem. Is there any other way to display the information in swing?
If you are not aware of -Xmx command line argument to Java, you should learn about that and try that as a short term workaround. See documentation here.
The larger issue, though, is whether you really need to keep all of these images in memory at the same time. For a table that is displaying images, you might want to load the image only if it is currently supposed to be displayed or in a row near to what is being displayed.
I don't see anything obviously wrong with the way that you are reading the images, but I haven't worked with I/O of images in Java much, so perhaps that could be improved too.
In outline,
Create thumbnail-sized copies of your images, as shown here and here, to make instances of ImageIcon; use a background thread, as shown here, to keep the GUI responsive.
In your TableModel, return ImageIcon from getColumnClass() for the image column; the default renderer will display it automatically.
Use an adjacent component or popup to display the full size image on demand.

How to reduce size of a multipart file in java

I have Java Spring MVC application in which there is an option to upload an image and save to the server. i have the following method:
#RequestMapping(value = "/uploaddocimagecontentsubmit", method = RequestMethod.POST)
public String createUpdateFileImageContentSubmit(#RequestParam("file") MultipartFile file, ModelMap model)
{
//methods to handle file upload
}
I am now trying to reduce the size of the image refering the following:
increasing-resolution-and-reducing-size-of-an-image-in-java and decrease-image-resolution-in-java
The problem I am facing is that in the above examples, we are dealing with java.io.File Objects which are saved to a specified location. I dont want to save the image. Is there any way that I can use something similar to compress my Multipart Image file and continue with the upload.
Why don't you resize it on the client before upload? That will save some bandwidth
BlueImp JQuery Upload can do this
It was my first time taking a deep dive into the ImageIO package. I came across the MemoryCacheImageOutputStream, which allows you to write an image output stream to an output stream, i.e. ByteArrayOutputStream. From there, The data can be retrieved using toByteArray() and toString(), after compression. I used toByteArray, as I am storing images to postgresql and it stores the images as a byte array. I know this is late, but I hope it helps someone.
private byte[] compressImage(MultipartFile mpFile) {
float quality = 0.3f;
String imageName = mpFile.getOriginalFilename();
String imageExtension = imageName.substring(imageName.lastIndexOf(".") + 1);
// Returns an Iterator containing all currently registered ImageWriters that claim to be able to encode the named format.
// You don't have to register one yourself; some are provided.
ImageWriter imageWriter = ImageIO.getImageWritersByFormatName(imageExtension).next();
ImageWriteParam imageWriteParam = imageWriter.getDefaultWriteParam();
imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // Check the api value that suites your needs.
// A compression quality setting of 0.0 is most generically interpreted as "high compression is important,"
// while a setting of 1.0 is most generically interpreted as "high image quality is important."
imageWriteParam.setCompressionQuality(quality);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// MemoryCacheImageOutputStream: An implementation of ImageOutputStream that writes its output to a regular
// OutputStream, i.e. the ByteArrayOutputStream.
ImageOutputStream imageOutputStream = new MemoryCacheImageOutputStream(baos);
// Sets the destination to the given ImageOutputStream or other Object.
imageWriter.setOutput(imageOutputStream);
BufferedImage originalImage = null;
try (InputStream inputStream = mpFile.getInputStream()) {
originalImage = ImageIO.read(inputStream);
} catch (IOException e) {
String info = String.format("compressImage - bufferedImage (file %s)- IOException - message: %s ", imageName, e.getMessage());
logger.error(info);
return baos.toByteArray();
}
IIOImage image = new IIOImage(originalImage, null, null);
try {
imageWriter.write(null, image, imageWriteParam);
} catch (IOException e) {
String info = String.format("compressImage - imageWriter (file %s)- IOException - message: %s ", imageName, e.getMessage());
logger.error(info);
} finally {
imageWriter.dispose();
}
return baos.toByteArray();
}

How do you access an attachment stored as MIME Part?

It seems to me there are two ways to store an attachment in a NotesDocument.
Either as a RichTextField or as a "MIME Part".
If they are stored as RichText you can do stuff like:
document.getAttachment(fileName)
That does not seem to work for an attachment stored as a MIME Part. See screenshot
I have thousands of documents like this in the backend. This is NOT a UI issue where I need to use the file Download control of XPages.
Each document as only 1 attachment. An Image. A JPG file. I have 3 databases for different sizes. Original, Large, and Small. Originally I created everything from documents that had the attachment stored as RichText. But my code saved them as MIME Part. that's just what it did. Not really my intent.
What happened is I lost some of my "Small" pictures so I need to rebuild them from the Original pictures that are now stored as MIME Part. So my ultimate goal is to get it from the NotesDocument into a Java Buffered Image.
I think I have the code to do what I want but I just "simply" can't figure out how to get the attachment off the document and then into a Java Buffered Image.
Below is some rough code I'm working with. My goal is to pass in the document with the original picture. I already have the fileName because I stored that out in metaData. But I don't know how to get that from the document itself. And I'm passing in "Small" to create the Small image.
I think I just don't know how to work with attachments stored in this manner.
Any ideas/advice would be appreciated! Thanks!!!
public Document processImage(Document inputDoc, String fileName, String size) throws IOException {
// fileName is the name of the attachment on the document
// The goal is to return a NEW BLANK document with the image on it
// The Calling code can then deal with keys and meta data.
// size is "Original", "Large" or "Small"
System.out.println("Processing Image, Size = " + size);
//System.out.println("Filename = " + fileName);
boolean result = false;
Session session = Factory.getSession();
Database db = session.getCurrentDatabase();
session.setConvertMime(true);
BufferedImage img;
BufferedImage convertedImage = null; // the output image
EmbeddedObject image = null;
InputStream imageStream = null;
int currentSize = 0;
int newWidth = 0;
String currentName = "";
try {
// Get the Embedded Object
image = inputDoc.getAttachment(fileName);
System.out.println("Input Form : " + inputDoc.getItemValueString("form"));
if (null == image) {
System.out.println("ALERT - IMAGE IS NULL");
}
currentSize = image.getFileSize();
currentName = image.getName();
// Get a Stream of the Imahe
imageStream = image.getInputStream();
img = ImageIO.read(imageStream); // this is the buffered image we'll work with
imageStream.close();
Document newDoc = db.createDocument();
// Remember this is a BLANK document. The calling code needs to set the form
if ("original".equalsIgnoreCase(size)) {
this.attachImage(newDoc, img, fileName, "JPG");
return newDoc;
}
if ("Large".equalsIgnoreCase(size)) {
// Now we need to convert the LARGE image
// We're assuming FIXED HEIGHT of 600px
newWidth = this.getNewWidth(img.getHeight(), img.getWidth(), 600);
convertedImage = this.getScaledInstance(img, newWidth, 600, false);
this.attachImage(newDoc, img, fileName, "JPG");
return newDoc;
}
if ("Small".equalsIgnoreCase(size)) {
System.out.println("converting Small");
newWidth = this.getNewWidth(img.getHeight(), img.getWidth(), 240);
convertedImage = this.getScaledInstance(img, newWidth, 240, false);
this.attachImage(newDoc, img, fileName, "JPG");
System.out.println("End Converting Small");
return newDoc;
}
return newDoc;
} catch (Exception e) {
// HANDLE EXCEPTION HERE
// SAMLPLE WRITE TO LOG.NSF
System.out.println("****************");
System.out.println("EXCEPTION IN processImage()");
System.out.println("****************");
System.out.println("picName: " + fileName);
e.printStackTrace();
return null;
} finally {
if (null != imageStream) {
imageStream.close();
}
if (null != image) {
LibraryUtils.incinerate(image);
}
}
}
I believe it will be some variation of the following code snippet. You might have to change which mimeentity has the content so it might be in the parent or another child depending.
Stream stream = session.createStream();
doc.getMIMEEntity().getFirstChildEntity().getContentAsBytes(stream);
ByteArrayInputStream bais = new ByteArrayInputStream(stream.read());
return ImageIO.read(bais);
EDIT:
session.setConvertMime(false);
Stream stream = session.createStream();
Item itm = doc.getFirstItem("ParentEntity");
MIMEEntity me = itm.getMIMEEntity();
MIMEEntity childEntity = me.getFirstChildEntity();
childEntity.getContentAsBytes(stream);
ByteArrayOutputStream bo = new ByteArrayOutputStream();
stream.getContents(bo);
byte[] mybytearray = bo.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(mybytearray);
return ImageIO.read(bais);
David have a look at DominoDocument,http://public.dhe.ibm.com/software/dw/lotus/Domino-Designer/JavaDocs/XPagesExtAPI/8.5.2/com/ibm/xsp/model/domino/wrapped/DominoDocument.html
There you can wrap every Notes document
In the DominoDocument, there such as DominoDocument.AttachmentValueHolder where you can access the attachments.
I have explained it at Engage. It very powerful
http://www.slideshare.net/flinden68/engage-use-notes-objects-in-memory-and-other-useful-java-tips-for-x-pages-development

Performance of JSoup and Bitmap Images

I've been working on an Android app where I am getting an RSS feed and I need to parse some additional HTML for image source links. So, I figured I would use JSoup and see how it went. It IS working and I can get the image src link correctly. However the .Parse method is taking a very long time to complete and I can't have the user waiting that long. All of this fetching of the RSS takes place in onStart() in the app by the way.
My ultimate goal is to retrieve the images from the src url's and display them next to article text. I've had my fair share of dealing with the common OutOfMemory errors in relation to the heap. As of now I seem to have sort of dealt with it. But I still cannot figure out why the loading of the program is taking so long. Right now there are 10 articles in the RSS feed and the HTML parsing for each one is not really long. Maybe someone can spot something stupid I'm doing and figure out why the loading of my program is taking so long. I would certainly appreciate it! Here is my code involving the images and Jsoup.
public static Bitmap parseForImg(String desc) throws IOException
{
Document doc = Jsoup.parse(desc);
Elements images = doc.select("img[src~=(?i)\\.(png|jpe?g|gif)]");
String imgURL = "";
Bitmap img = null;
if(images.size() > 0)
{
for (Element image : images)
{
imgURL = image.attr("src");
break;
}
String editedImgURL = imgURL.replace("/sites/", "https://www.").trim();
img = ArticleRSSReader.grabImgFromURL(editedImgURL);
}
else
{
//in the event there is no image related to a description in the rss feed, just display
//the logo for now...
InputStream inputS = MainActivity.globalTHIS.getResources().getAssets().open("defaultlogo.png");
img = BitmapFactory.decodeStream(inputS);
//no need to grab image from url, just return
}
return img;
}
public static Bitmap grabImgFromURL(String imageURLLoc)
{
URL imageURL = null;
Bitmap resizedBit = null;
try
{
imageURL = new URL(imageURLLoc);
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
try
{
HttpURLConnection connection = (HttpURLConnection) imageURL
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream inputStream = connection.getInputStream();
//bitmap = BitmapFactory.decodeStream(inputStream);// Convert to
// bitmap
// image_view.setImageBitmap(bitmap);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
options.inPurgeable = true;
resizedBit = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(inputStream,null,options), 100, 100, false);
}
catch (IOException e)
{
e.printStackTrace();
}
return resizedBit;
}

Webservice consuming image from Android camera only on lower resolutions

I have a webservice running and ready to consume images produced by my Android tablet camera (Samsumg Galaxy TAB 10.1).
It works perfectly when consuming images taken at 1024x768 resolution (0.8M). However, when using the tablet's highest resolution (2048x1536, or 3.2M), the image saved simply does not work. It saves a broken image file with 0kb size.
This is the code related to the image-saving in the webservice:
public static void saveFile(final InputStream file, final String filePath) throws IOException {
OutputStream out = new FileOutputStream(new File(filePath.trim()));
int read = 0;
byte[] bytes = new byte[2048];
while ((read = file.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
file.close();
out.flush();
out.close();
}
I've already tried increasing the byte array size, but it didn't help.
The file variable is produced like this:
final InputStream image = data.getImage().getDataHandler().getInputStream();
Where data is a object consumed via a multipart request made by the webservice to Android, like this.
Any ideas?

Categories