PNG Image is badly stained when set as LWUIT Form's background image - java-me

I want to make a png Image as the background image of a LWUIT Form. The problem is that the image is altered : there are stains in the image after setting it as the Form's background image. Here are codes :
public class DetailPhotoClient extends Form implements ActionListener {
private Command options, delete, back, annuler, ok;
private GaleriePhotos backForm;
private FileConnection fcFile;
private Image sourceImage, fullImage;
private InputStream is;
private PopupMenu popup;
public DetailPhotoClient(GaleriePhotos prevForm, String absolutePathphotoName)
{
super();
back = new Command("Retour");
options = new Command("Options");
this.addCommand(back);
this.addCommand(options);
this.addCommandListener(this);
delete = new Command("Supprimer");
annuler = new Command("Annuler");
ok = new Command("Ok");
backForm = prevForm;
try {
fcFile = (FileConnection) Connector.open(absolutePathphotoName, Connector.READ);
is = fcFile.openInputStream();
sourceImage = Image.createImage(is);
fullImage = createThumbnail(sourceImage);
setBgImage(fullImage);
is.close();
fcFile.close();
} catch (IOException ex) {
handleException();
} catch (OutOfMemoryError oom) {
handleOOM();
}
}
private Image createThumbnail(Image image) {
Image thumb = image.scaled(this.getPreferredW(), this.getPreferredH());
return thumb;
}
...
}
I noticed that when I open the photo manually , that is from the phone memory's photo folder , then the photo is not altered !
So how to make the image not altered when setting it as the Form's background image ?

LWUIT uses scaling for background images by default. It will always scale the images unless you explicitly ask the style for different behavior e.g. tiling, aligning etc. try:
myForm.getStyle().setBackgroundType(Style.BACKGROUND_IMAGE_ALIGNED_CENTER);

Validate whether the image read from file, i.e. sourceImage, is as seen in the native phone device. If not so the problem lies here.
If you are able to see the sourceImage correct, than there are some things to be evaluated in getting a scaled image.
In case your form contentPane's width / height is smaller than the images width / height than a better option would be use
Image thumb = image.scaledSmallerRatio(this.getWidth(), this.getHeight());
NOTE: Yes, its getWidth() and not getPreferredW(). If you don't get desired result than try scaling with getPreferredW().
In case your image's width / height is smaller than form contentPane's width / height, you might as well do not scale it since the image will fit the screen.

Related

Can i add SVG image in ImageView?

I have an imageView : width=200 ,height=150 ,when i upload a big image (.jpg) for example image :1200*500 pixels and i minus the width ad height of imageView ,the image lose his quality ,it will be not clear ,can i find a way to add .svg or vector image in imageView ?
I found an option by using Transcoder API of batik library project from apache and convert the resultant BufferedImage to a JavaFX Image.
Edit:
Transcoder API provide classes to convert SVG document to PNG,JPG,TIFF,we can use this sample of code to create a JPEG image from SVG path,
import java.io.*;
import org.apache.batik.transcoder.image.JPEGTranscoder;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
public class SaveAsJPEG {
public static void main(String[] args) throws Exception {
// Create a JPEG transcoder
JPEGTranscoder t = new JPEGTranscoder();
// Set the transcoding hints.
t.addTranscodingHint(JPEGTranscoder.KEY_QUALITY,
new Float(.8));
// Create the transcoder input.
String svgURI = new File("C:\Users\Blue\Downloads\icon8_smile.svg").toURL().toString();
TranscoderInput input = new TranscoderInput(svgURI);
// Create the transcoder output.
OutputStream ostream = new FileOutputStream("icon8_smile.jpg");
TranscoderOutput output = new TranscoderOutput(ostream);
// Save the image.
t.transcode(input, output);
// Flush and close the stream.
ostream.flush();
ostream.close();
System.exit(0);
}
}
By this way we can transform an SVG vector image to other image based on pixels.
Other option we can add it to our code ,for help us to define the size of output image :
t.addTranscodingHint(JPEGTranscoder.KEY_WIDTH, new Float(250));
This line of code help us to define the size of image according to size of ImageView and we can make some changes like this :
t.addTranscodingHint(JPEGTranscoder.KEY_WIDTH, imageView.getFitWidth();

Scale background image during screen rotation in android using Tabris

I have following server side code in the top level page to set background image for all pages in the app.
#Override
public void createContent(final Composite parent, final PageData oData) {
Image bg = ResourceManager.getImage( LnfSettings.IMAGE_PAGE_BACKGROUND );
Composite comp = parent.getParent();
int width = comp.getDisplay().getClientArea().width;
int height = comp.getDisplay().getClientArea().height;
comp.setBackgroundImage( new Image( bg.getDevice(), bg.getImageData().scaledTo(
width, height ) ) );
... more code here to create layout and contents
}
Above code correctly sets background for all pages and also scaled image to fit with the different screen sizes. But if I rotate the screen, image doesn't get scaled according to the new screen dimension. How to deal with this issue? I am using Tabris 1.4.
You can add a resize listener to your composite like this:
comp.addListener(SWT.Resize, listenerComp);
Listener listenerComp = new Listener() {
#Override
public void handleEvent(Event event) {
...
}
};
Just get sure you cache your scaled Images so you do not scale and create new images on every rotation.

How to create a circular bufferedimage rather than creating a rectangular one in Java using Graphics

I need to create a bufferedimage
(circular type) but I am able to create only rectangular type. Then I want to create a oval inside the bufferedimage with some configurations and finally i want to draw a rectangular icon inside the circular shape which should be inserted on the circular shape and not on the rectangular bufferedimage.
Now i am able to do the following
BufferedImage img = "SomeImage.png";
BufferedImage bfImage = new BufferedImage(200,200,BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = bfImage.createGraphics();
graphics.fillOval(0, 0, 200, 200);
graphics.drawImage(img, 0, 0, null);
(This creates a circular oval inside the bfImage object)
Now i need to draw "img" which is rectangular in shape of say 100*100 size.
This i can draw using
When i am doing this my final image is getting drawn in the Rectangular BfImage, which i dont want.I want the image "img" to be drawn in the circular oval and it should not come outside the boundaries of the circular oval shape.
In short instead of drawing my final image on the rectangular bfImage can i have a circular bfImage on which i can directly draw my image.
Any logic to do this in Java2D using graphics.
I've never encountered a "circular image" in the sense of a two dimensional array that is not in rectangular form. If all you are concerned about is that the pixels outside the circle are not visible, just set the alpha to 0 for those pixels. An easy way to do this is to fill the entire rectangular image with ARGB(0,0,0,0) first and then draw whatever else you want.
Also, not that if you intent to persist this buffer as an image file, you must make sure that you export/save to a format like PNG or TIFF that supports transparency.
As #justinzane says, you can't have a truly circular image. All BufferedImages will be rectangular.
But: You can achieve the effect you are after, by using the AlphaComposite class, and the rule AlphaComposite.SrcIn. I've added a fully running example, plus a screen shot below, the compose method is the important part.
public class AlphaCompositeTest {
private static BufferedImage compose(final BufferedImage source, int w, int h) {
BufferedImage destination = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = destination.createGraphics();
try {
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics.setColor(Color.BLACK); // The color here doesn't really matter
graphics.fillOval(0, 0, destination.getWidth(), destination.getHeight());
if (source != null) {
graphics.setComposite(AlphaComposite.SrcIn); // Only paint inside the oval from now on
graphics.drawImage(source, 0, 0, null);
}
}
finally {
graphics.dispose();
}
return destination;
}
public static void main(String[] args) throws IOException {
final BufferedImage original = ImageIO.read(new File("lena.png"));
final BufferedImage template = compose(null, original.getWidth(), original.getHeight());
final BufferedImage composed = compose(original, original.getWidth(), original.getHeight());
SwingUtilities.invokeLater(new Runnable() {
#Override public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new BorderLayout(10, 10));
panel.add(new JLabel("+", new ImageIcon(template), SwingConstants.LEFT), BorderLayout.WEST);
panel.add(new JLabel("=", new ImageIcon(original), SwingConstants.LEFT), BorderLayout.CENTER);
panel.add(new JLabel(new ImageIcon(composed)), BorderLayout.EAST);
frame.add(new JScrollPane(panel));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
See for example the Compositing tutorial for more info and examples.

How to save canvas as an image in j2me?

I want to save the current state of the canvas as an image as I will use it in the next pointerevent. If I use repaint it will clear the canvas and I can't get the previous state of canvas. So, I want to save it as image and then iterate it over and over so that finally I can make out what I want.
The final question is how to save the canvas as image ?.
Or Is there any possibility of converting the Graphics object to a byte array ?
You can't save the canvas as an image.
You have to create an image first, and then you can paint onto that image.
Basically that means that your midlet will be doing more work, since you first have to draw onto your image, and then you have to draw that image onto the canvas. But it's the only way you can do what you want.
Create an Image with same size (width and height) of the screen. When you want to save the canvas state call Canvas.paint passing the image Graphics.
class MyCanvas extends Canvas {
private Image lastScreen;
protected void sizeChanged(int w, int h) {
if (lastScreen == null || w != lastScreen.getWidth()
|| h != lastScreen.getHeight) {
lastScreen = Image.createImage(w, h);
}
}
protected void paint(Graphics g) {
// paint the whole screen
}
protected void pointerReleased(int x, int y) {
paint(lastScreen.getGraphics());
}
}

Is there a way to set a default image for ImageLoader?

I am using MonoTouch.Dialog in my app; however, the form in question is implemented using a UIViewController to which which I added a TableView (so I can also add a UIToolbar).
I love the ImageLoader that comes in MonoTouch.Dialog.Utilities and am trying to use it in the GetCell() method of the DataSource for the TableView to render an image from a URL.
var callback = new ImageLoaderCallback(controller, cell.ImageView, indexPath); // ImageLoaderCallback implements IImageUpdated
cell.ImageView.Image = ImageLoader.DefaultRequestImage(new Uri(picFV.Value), callback);
The problem is that until the URL is downloaded, the space for the ImageView is collapsed (so that the text to the right of the image is actually anchored on the left of the table).
What I'd like to do is display a temporary local image which has the same dimensions as the downloaded image, so that when the ImageLoader is done retrieving and rendering the image, the user experience isn't as jarring.
I tried to do the following in the GetCell() call... cell.ImageView.Image is set to some other image (not shown below), and then I get a reference to what comes back from ImageLoader.DefaultRequestImage.
var image = ImageLoader.DefaultRequestImage(new Uri(picFV.Value), callback);
callback.Image = image;
the last line stuffs the image reference returned by ImageLoader into the callback's state, and the callback will replace the cell's ImageView.Image when the ImageLoader is done (see below):
// callback class for the MonoTouch.Dialog image loader utility
private class ImageLoaderCallback : IImageUpdated
{
private ListViewController controller;
private UIImageView imageView;
private NSIndexPath indexPath;
public ImageLoaderCallback(ListViewController c, UIImageView view, NSIndexPath path)
{
controller = c;
imageView = view;
indexPath = path;
}
public UIImage Image { get; set; }
void IImageUpdated.UpdatedImage(Uri uri)
{
if (uri == null)
return;
if (Image != null)
imageView.Image = Image;
// refresh the display for the row of the image that just got updated
controller.TableView.ReloadRows(new NSIndexPath [] { indexPath }, UITableViewRowAnimation.None);
}
}
However, this doesn't work because it appears that the ImageLoader needs to be "pulled" by the TableView when it tries to render its ImageView (i.e. the ImageLoader callback never gets invoked because no one is pulling on the URL).
How do I accomplish this scenario?
Thanks!
I know this is an old question now, but I came across it when searching for the same thing and have seen the following blog post which states how to accomplish this. I haven't yet tried it out but hopefully it might help you or anyone else coming across this in the future: http://yusinto.blogspot.co.uk/2012/05/background-image-downloading-with.html

Resources