I am facing a problem while using encodedImage. When a user logins into the app, the first form after successful login has an image. And the image is causing me issues upon retrieving it.
When the user captures an image in the app, I convert it to a base64 string which I send to the server. The code for that is:
ImageIO img = ImageIO.getImageIO();
ByteArrayOutputStream out = new ByteArrayOutputStream();
img.save(et, out, ImageIO.FORMAT_JPEG, 1);
byte[] ba = out.toByteArray();
String userImage64 = Base64.encodeNoNewline(ba);
et is the captured image. So I store the string userImage64 in the server.
When I retrieve the base64, I decode it and convert it to an EncodedImage. The code is:
String url = new JSONObject(result.getResponseData()).getString("photo");
byte[] b = Base64.decode(url.getBytes());
Image icon = EncodedImage.create(b);
When I am on the simulator, everything flows smoothly. The images display and everything works very well.
My issue is, when I put the app on an android device, it doesn't work. It shows me a toast of successful login and just stops there. So i did some debugging and realized that issue is with the three lines of converting from base64 to image. When I comment out the three lines, everything works very well. Where could I be going wrong?
EDIT
Below is the code I use to capture a photo:
String i = Capture.capturePhoto();
if (i != null) {
try {
final Image newImage = Image.createImage(i);
Image roundedMask = Image.createImage(rich.minScreensize() / 4, rich.minScreensize() / 4, 0xff000000);
Graphics gra = roundedMask.getGraphics();
gra.setColor(0xffffff);
gra.fillArc(0, 0, rich.minScreensize() / 4, rich.minScreensize() / 4, 0, 360);
Object masked = roundedMask.createMask();
cropImage(newImage, rich.minScreensize() / 4, rich.minScreensize() / 4, et -> {
if (editing) {
try {
ImageIO img = ImageIO.getImageIO();
ByteArrayOutputStream out = new ByteArrayOutputStream();
img.save(et, out, ImageIO.FORMAT_JPEG, 1);
byte[] ba = out.toByteArray();
userImage64 = Base64.encodeNoNewline(ba);
et = et.applyMask(masked);
logoimage.setIcon(et);
///removed unnecessary code
logoimage.getComponentForm().revalidate();
} catch (IOException ex) {
}
} else {
et = et.applyMask(masked);
logoimage.setIcon(et);
}
});
} catch (IOException ex) {
Log.p("Error loading captured image from camera", Log.ERROR);
}
}
Inside there is code I use to crop the photo and that is code is:
private void cropImage(Image img, int destWidth, int destHeight, OnComplete<Image> s) {
Form previous = getCurrentForm();
Form cropForm = new Form("", new LayeredLayout());
Label toobarLabel = new Label("New Holder", "Toolbar-HeaderLabel");
cropForm.setTitleComponent(toobarLabel);
Toolbar mainToolbar = new Toolbar();
mainToolbar.setUIID("ToolBar");
cropForm.setToolbar(mainToolbar);
Label moveAndZoom = new Label("Move and zoom the photo to crop it");
moveAndZoom.getUnselectedStyle().setFgColor(0xffffff);
moveAndZoom.getUnselectedStyle().setAlignment(CENTER);
moveAndZoom.setCellRenderer(true);
cropForm.setGlassPane((Graphics g, Rectangle rect) -> {
g.setColor(0x0000ff);
g.setAlpha(150);
Container cropCp = cropForm.getContentPane();
int posY = cropForm.getContentPane().getAbsoluteY();
GeneralPath p = new GeneralPath();
p.setRect(new Rectangle(0, posY, cropCp.getWidth(), cropCp.getHeight()), null);
if (isPortrait()) {
p.arc(0, posY + cropCp.getHeight() / 2 - cropCp.getWidth() / 2,
cropCp.getWidth() - 1, cropCp.getWidth() - 1, 0, Math.PI * 2);
} else {
p.arc(cropCp.getWidth() / 2 - cropCp.getHeight() / 2, posY,
cropCp.getHeight() - 1, cropCp.getHeight() - 1, 0, Math.PI * 2);
}
g.fillShape(p);
g.setAlpha(255);
g.setColor(0xffffff);
moveAndZoom.setX(0);
moveAndZoom.setY(posY);
moveAndZoom.setWidth(cropCp.getWidth());
moveAndZoom.setHeight(moveAndZoom.getPreferredH());
moveAndZoom.paint(g);
});
final ImageViewer viewer = new ImageViewer();
viewer.setImage(img);
cropForm.add(viewer);
cropForm.getToolbar().addMaterialCommandToRightBar("", FontImage.MATERIAL_CROP, e -> {
previous.showBack();
s.completed(viewer.getCroppedImage(0).
fill(destWidth, destHeight));
});
cropForm.getToolbar().addMaterialCommandToLeftBar("", FontImage.MATERIAL_CANCEL, e -> previous.showBack());
cropForm.show();
}
Related
I'm implementing 3D demo application using Babylonjs library for 3D Demo.I'm importing 3D model from S3 and adding texture image on top of material in Reactjs.
But when i add texture image on top of material, rest of area on 3D model gets black color and i want get rid of it. Code works fine in Babylon playground but fails in React app.
Here is the source code
var mat = new BABYLON.CustomMaterial("mat", scene);
mat.diffuseTexture = new BABYLON.Texture(textureImage, scene, false, false);
materialedMeshes.forEach(mesh => mesh.material = mat);
mat.emissiveColor = new BABYLON.Color3(1, 1, 1);
// mat.diffuseColor = new BABYLON.Color3(1, 0, 1);
// mat.specularColor = new BABYLON.Color3(0.5, 0.6, 0.87);
// mat.emissiveColor = new BABYLON.Color3(1, 1, 1);
// mat.ambientColor = new BABYLON.Color3(0.23, 0.98, 0.53);
mat.diffuseTexture.uOffset = -0.1000;
mat.diffuseTexture.vOffset = -1.1800;
mat.diffuseTexture.uScale = 1.2200;
mat.diffuseTexture.vScale = 2.2200;
mat.diffuseTexture.uAng = Math.PI;
mat.diffuseTexture.wrapU = BABYLON.Constants.TEXTURE_CLAMP_ADDRESSMODE;
mat.diffuseTexture.wrapV = BABYLON.Constants.TEXTURE_CLAMP_ADDRESSMODE;
mat.Fragment_Custom_Alpha(`
if (baseColor.r == 0. && baseColor.g == 0. && baseColor.b == 0.) {
baseColor.rgb = vec3(0.85, 0.85, 0.85);
}
baseColor.rgb = mix(vec3(0.85, 0.85, 0.85), baseColor.rgb, baseColor.a);
`)
I tried to use the following code with the purpose to record some videos with real devices (Android and iPhone) and to see the resulting file sizes. But it doesn't work... it seems to record, but it doesn't play the resulting videos neither on Android nor iOS.
I wrote the following code merging some examples in the Codename One API. What's wrong?
Form hi = new Form("Capture", BorderLayout.center());
Container cnt = new Container(BoxLayout.y());
hi.setToolbar(new Toolbar());
Style s = UIManager.getInstance().getComponentStyle("Title");
FontImage icon = FontImage.createMaterial(FontImage.MATERIAL_VIDEOCAM, s);
FileSystemStorage fs = FileSystemStorage.getInstance();
String recordingsDir = fs.getAppHomePath() + "recordings/";
fs.mkdir(recordingsDir);
try {
for (String file : fs.listFiles(recordingsDir)) {
Button mb = new Button(file.substring(file.lastIndexOf("/") + 1) + " - " + (int) (fs.getLength(recordingsDir + file) / 1024.0 / 1024.0 * 100) / 100.0 + " MB");
mb.addActionListener((e) -> {
try {
Media video = MediaManager.createMedia(recordingsDir + file, true);
hi.removeAll();
hi.add(BorderLayout.CENTER, new MediaPlayer(video));
hi.revalidate();
} catch (IOException err) {
Log.e(err);
}
});
cnt.add(mb);
}
hi.add(BorderLayout.CENTER, cnt);
hi.getToolbar().addCommandToRightBar("", icon, (ev) -> {
try {
String file = Capture.captureVideo();
if (file != null) {
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MMM-dd-kk-mm");
String fileName = sd.format(new Date());
String filePath = recordingsDir + fileName;
Util.copy(fs.openInputStream(file), fs.openOutputStream(filePath));
Button mb = new Button(file.substring(file.lastIndexOf("/") + 1) + " - " + (int) (fs.getLength(filePath) / 1024.0 / 1024.0 * 100) / 100.0 + " MB");
mb.addActionListener((e) -> {
try {
Media video = MediaManager.createMedia(filePath, true);
hi.removeAll();
hi.add(BorderLayout.CENTER, new MediaPlayer(video));
hi.revalidate();
} catch (IOException err) {
Log.e(err);
}
});
cnt.add(mb);
cnt.getParent().revalidate();
}
} catch (IOException err) {
Log.e(err);
}
});
} catch (IOException err) {
Log.e(err);
}
hi.show();
This is what I see on iPhone X after tapping a Button to open a recorded video (that is very similar to what I see on Android 7):
I spent so much time looking at this it's embarrassing...
Change this:
Form hi = new Form("Capture", BorderLayout.center());
To this:
Form hi = new Form("Capture", new BorderLayout());
The former gives the component its preferred size. The latter scales it to take up available space. The preferred size is zero on most platforms since the video needs to load for preferred size to apply. When it loads one would need to reflow the layout.
Android OS version 7.1.1, following code display blank screen first time after download the App. Have to kill the App and open it again to work normally. Please advise.
Code:
Container cc = new Container(BoxLayout.y());
cc.setScrollableY(true);
TextArea ta = new TextArea(Util.readToString(is));
ta.setEditable(false);
ta.setUIID("Label");
Button b = new Button("Terms of Service");
b.addActionListener(e3 -> {
try {
FileSystemStorage fs = FileSystemStorage.getInstance();
final String homePath = fs.getAppHomePath();
String fileName = homePath + "Terms of Service.pdf";
Util.copy(Display.getInstance().getResourceAsStream(getClass(), "/Terms of Service.pdf"), fs.openOutputStream(fileName));
Display.getInstance().execute(fileName);
} catch (IOException ex) {
}
});
cc.add(ta);
CheckBox rememberMe1 = new CheckBox();
rememberMe1.setSelected(false);
rememberMe1.setHeight(Display.getInstance().convertToPixels(10.0f));
rememberMe1.setAutoSizeMode(true);
b.setAutoSizeMode(true);
setSameHeight(rememberMe1, l11, b);
cc.add(FlowLayout.encloseIn(rememberMe1, b));
Im using a MultiList to display some result from a web service but the address is not showing up completely.
Please this picture
The first address should be "Jalan Gertak Merah, 80000 Johor Bahru, Johor, Malaysia" and not "Jalan Gertak Merah, 80"
How can I correct this please.
This is my code:
Style s = UIManager.getInstance().getComponentStyle("Button");
FontImage p = FontImage.createMaterial(FontImage.MATERIAL_PORTRAIT, s);
EncodedImage placeholder = EncodedImage.createFromImage(p.scaled(p.getWidth() * 3, p.getHeight() * 4), false);
f.setTitle("Tourist Attractions");
getattractive();
ArrayList arr = (ArrayList) response.get("results");
for (Object m : arr) {
Map ma = (Map) m;
address = (String) ma.get("formatted_address");
name = (String) ma.get("name");
icon = (String) ma.get("icon");
data.add(createListEntry(name, address, icon));
}
DefaultListModel<Map<String, Object>> model = new DefaultListModel<>(data);
MultiList ml = new MultiList(model);
ml.getUnselectedButton().setIconName("icon_URLImage");
ml.getSelectedButton().setIconName("icon_URLImage");
ml.getUnselectedButton().setIcon(placeholder);
ml.getSelectedButton().setIcon(placeholder);
findContainer(f).add(BorderLayout.CENTER, ml);
c.addComponent(bn);
bn.addActionListener((ActionEvent evt) -> {
System.exit(0);
});
findContainer(f).add(BorderLayout.SOUTH, c);
f.getComponentForm().revalidate();
I have universal app created for Win 10 mobile which captures photo. I want to add stamp (some text) to my photo. Is it possible? It seems working with bitmap is really difficult in universal applications
Check this link:
How to add wartermark text/image to a bitmap in Windows Store app
Or better use Win2D library (you can find it on NuGet) and snippet like this:
CanvasDevice device = CanvasDevice.GetSharedDevice();
CanvasRenderTarget offscreen = new CanvasRenderTarget(device, 500, 500, 96);
cbi = await CanvasBitmap.LoadAsync(device, "mydog.jpg");
using (var ds = offscreen.CreateDrawingSession())
{
ds.DrawImage(cbi);
var format = new CanvasTextFormat()
{
FontSize = 24,
HorizontalAlignment = CanvasHorizontalAlignment.Left,
VerticalAlignment = CanvasVerticalAlignment.Top,
WordWrapping = CanvasWordWrapping.Wrap,
FontFamily = "Tahoma"
};
var tl = new CanvasTextLayout(ds, "Some text", format, 200, 50); // width 200 and height 50
ds.DrawTextLayout(tl, 10, 10, Colors.Black);
tl.Dispose();
}
using (var stream = new InMemoryRandomAccessStream())
{
stream.Seek(0);
await offscreen.SaveAsync(stream, CanvasBitmapFileFormat.Png);
BitmapImage image = new BitmapImage();
image.SetSource(stream);
img.Source = image;
}