Hi
I'm having a problem with images I cannot figure out, hope you can help me out…
What I'm trying to do is download and place a png scaling down if necessary to fit the screen width.
My assumption: If the height of the image is larger than the height of the device, then the image is not rendered on devices but it is on simulator with no problem.
The problematic image is 1536x4272 and 1MB.
BUT the same image scaled to 768x2136 and 714KB works fine both on simulator and devices, so my assumption might not be right and I'm totally lost. Or maybe it's a problem with the image, but then why is it working on simulator?
To scale the image I'm setting the background of a Label. As I said The code below works on simulator but not on iOS or Android.
if(current != null){ current.show(); return; } Form f = new Form(new BoxLayout(BoxLayout.Y_AXIS)); f.setScrollableY(true); Container loading = new Container(new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE)).add(BorderLayout.CENTER, new InfiniteProgress()); Util.downloadImageToFileSystem("https://dl.dropboxusercontent.com/u/47281022/IMGP0.png", FileSystemStorage.getInstance().getAppHomePath() + FileSystemStorage.getInstance().getFileSystemSeparator() + "IMGP0", new CallbackAdapter(){ @Override public void onSucess(Object value) { Image img = (Image) value; int imgHeightDevice = (Display.getInstance().getDisplayWidth() * img.getHeight()) / img.getWidth(); Label l = new Label() { @Override protected Dimension calcPreferredSize() { return new Dimension(Display.getInstance().getDisplayWidth(), imgHeightDevice); } }; l.getAllStyles().setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FIT); l.getAllStyles().setBgImage(img); f.replace(loading, l, null); f.repaint(); } }); f.addComponent(loading); f.show(); }
public void start() { if(current != null){ current.show(); return; } Form f = new Form(new BoxLayout(BoxLayout.Y_AXIS)); f.setScrollableY(true); Container loading = new Container(new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE)).add(BorderLayout.CENTER, new InfiniteProgress()); Util.downloadImageToFileSystem("https://dl.dropboxusercontent.com/u/47281022/IMGP0.png", FileSystemStorage.getInstance().getAppHomePath() + FileSystemStorage.getInstance().getFileSystemSeparator() + "IMGP0", new CallbackAdapter(){ @Override public void onSucess(Object value) { Image img = (Image) value; img = img.scaledWidth(Display.getInstance().getDisplayWidth()); Label l = new Label(img); public class Prueba { private Form current; final static String[] resolutions = new String[]{"1536x4272.png", "1536x3272.png", "768x2136.png"}; public void init(Object context) { Toolbar.setGlobalToolbar(true); } public void start() { if(current != null){ current.show(); return; } Form f1 = new Form(new FlowLayout(Component.CENTER)); f1.setTransitionOutAnimator(CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL, false, 300)); Command back = new Command("Back") { @Override public void actionPerformed(ActionEvent evt) { f1.showBack(); } }; Button b1 = new Button ("Image " + resolutions[0]); Button b2 = new Button ("Image " + resolutions[1]); Button b3 = new Button ("Image " + resolutions[2]); Container c1 = new Container(new FlowLayout()); c1.add(b1).add(b2).add(b3); int[] selected = new int[1]; String[] downloadLink = new String[1]; b1.addActionListener((evt) -> { selected[0] = 0; downloadLink[0] = "https://dl.dropboxusercontent.com/u/47281022/IMGP0_" + resolutions[0]; showImage(back, selected, downloadLink); }); b2.addActionListener((evt) -> { selected[0] = 1; downloadLink[0] = "https://dl.dropboxusercontent.com/u/47281022/IMGP0_" + resolutions[1]; showImage(back, selected, downloadLink); }); b3.addActionListener((evt) -> { selected[0] = 2; downloadLink[0] = "https://dl.dropboxusercontent.com/u/47281022/IMGP0_" + resolutions[2]; showImage(back, selected, downloadLink); }); f1.add(c1); f1.show(); } private void showImage(Command back, int[] selected, String[] downloadLink) { Form f2 = new Form(new BoxLayout(BoxLayout.Y_AXIS)); f2.setTransitionOutAnimator(CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL, false, 300)); f2.setBackCommand(back); f2.getToolbar().addCommandToLeftBar(back); f2.show(); String path = FileSystemStorage.getInstance().getAppHomePath() + "IMGP0_"; if (FileSystemStorage.getInstance().exists(path + resolutions[selected[0]])) { try { EncodedImage img = EncodedImage.create(FileSystemStorage.getInstance().openInputStream(path + resolutions[selected[0]])); int imgHeightDevice = (Display.getInstance().getDisplayWidth() * img.getHeight()) / img.getWidth(); Label l = new Label() { @Override protected Dimension calcPreferredSize() { return new Dimension(Display.getInstance().getDisplayWidth(), imgHeightDevice); } }; l.getAllStyles().setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FIT); l.getAllStyles().setBgImage(img); f2.add(l); f2.repaint(); } catch (IOException io) { } } else { Util.downloadImageToFileSystem(downloadLink[0], path + resolutions[selected[0]], new CallbackAdapter(){ @Override public void onSucess(Object value) { Image img = (Image) value; int imgHeightDevice = (Display.getInstance().getDisplayWidth() * img.getHeight()) / img.getWidth(); Label l = new Label() { @Override protected Dimension calcPreferredSize() { return new Dimension(Display.getInstance().getDisplayWidth(), imgHeightDevice); } }; l.getAllStyles().setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FIT); l.getAllStyles().setBgImage(img); f2.add(l); f2.repaint(); } }); } } public void stop() { current = Display.getInstance().getCurrent(); } public void destroy() { }}
There are some things that makes me doubt about your explanation:
- If the image is 768x4096, and therefore does not need scaling on 768x1024 device, it shows ok on that device.
- The image also shows fine if I add this to the code.
img = img.scaledWidth(Display.getInstance().getDisplayWidth());Right before:
l.getAllStyles().setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FIT);
l.getAllStyles().setBgImage(img);
So it seems that there is something wrong in the process of scaling when using the background image scaled.
Can it be fixed?
If not, I guess that I'll have to scale the images on the server side. I have tried Cloudinary and works fine, but I'm not sure the free cuota is enough for me...