I am developping an application that uses the Camera preview, take picture, and zoom functions.
I am trying to remain compatible with the Android API level 7 (2.1 Eclair), which does not implement Camera.Parameters.getMaxZoom(), Camera.Parameters.setZoom(), etc, so I have to use the String parameters returned by the hardware. For example:
final String zoomSupportedString = parameters.get("zoom-supported"); // parameters is a Camera.Parameters
final boolean zoomSupported = (zoomSupportedString != null ? Boolean.parseBoolean(zoomSupportedString) : false);
if (zoomSupported) {
// Computes the min an max zoom levels for taking a picture:
final int minTake = parameters.getInt("taking-picture-zoom-min");
final int maxTake = parameters.getInt("taking-picture-zoom-max");
// etc.
}
But not all the devices use the same parameters, and I couldn't find any valid camera parameters list on the internet.
By checking the values returned by Camera.Parameters.flatten() (see doc) on a HTC I could find "zoom-supported", "taking-picture-zoom-min", "taking-picture-zoom-max" and "max-zoom". And surprisingly, I have found no "min-zoom".
But the parameter "taking-picture-zoom-min" doesn't exist on Samsung Galaxy S, for example, and this leads null to be returned and getInt() to throw a NumberFormatException: 'null' cannot be parsed as an integer.
Knowing that I am trying to remain compatible with Android-7, is there any better way to handle the zoom than using the string values returned by the hardware? And if so, is it possible to find somewhere a list of all the valid zoom parameters (or even a list by vendor)?
i know it's an old topic, but for those that are searching for Camera zoom... i had the same issue and now that i have 2 android devices which work differently, both had something in commmon.
Camera.Parameters.setZoom(int value) didn't work on both of them, so i started testing. One device has "taking-picture-zoom-...;" but both devices have "zoom=...;" in the Camera.Parameters. On the device that has "taking-picture-zoom-...;", if i use Camera.Parameters.set("zoom", int value) it would crash, while on the other it would work just fine. So, my solution is, when initializing the camera I store a boolean that holds true for Camera.Parameters.get("taking-picture-zoom")!=null, and false otherwise. From that moment on, when setting zoom, just check the boolean and use the appropriate zoom-command... and that's it, works like a charm ! ofcourse, you could also just make a String hold the appropriate command and use that when setting zoom.
Related
For some reason, this code always returns 0, no matter where I am
public Long getClosestLinkID()
{
GeoCoordinate cur = HereMapsManager.instance.getPositionAnchor(); //returns my current position
Long closest = -1L;
RoadElement closest_elem = RoadElement.getRoadElement(cur, "fre");
if (closest_elem != null) {
closest = closest_elem.getPermanentDirectedLinkId();
}
return closest;
}
It finds a valid RoadElement, but calling getPermanentDirectedLinkId() (or getPermanentLinkId()) constantly returns 0.
Now, the documentation says:
Returns:
Permanent Link ID with direction of this element or 0 if not available.
So I tried with random coordinates on the map a little bit everywhere on the roads in France, and it keeps returning 0. I'm lost here.
getPermanentDirectedLinkId and getPermanentLinkId property is unavailable when the public transport mode RouteOptions.TransportMode#PUBLIC_TRANSPORT is used. For all the other transport modes, it is available only in routes calculated with the online connectivity mode. You should set your Connectivity explicitly to ONLINE(setConnectivity(Connectivity.ONLINE)).
Also, check if you are in one of the below two modes:
Tracking - NavigationManager.startTracking()
Navigation - NavigationManager.startNavigation()
This is required inorder to map match your location to a route.
You have to explicitly download and use offline maps as well to get this information.
Editing to add more information based on the customer comment below: You can check the classes and methods supported for your SDK by looking up the below pages
Starter SDK: {SDK-Download-location}/HERE_Android_SDK_Starter_v3.8_65/HERE-sdk/libs/docs/mapsdoc/index.html
Premium SDK: {SDK-Download-location}/HERE_Android_SDK_Premium_v3.8.0.104/sdk/HERE-sdk/libs/docs/mapsdoc-hybridplus/index.html
I'm attempting to extract the white balance parameters from the auto white balance algorithm in the S9. On every other device I've tested, it gives meaningful parameters back (the numbers have a floating point precision of like 6 digits and are constantly changing) but the S9 appears to round it's result parameters to the nearest whole number which ends up being giving some very poor results in terms of color balance. Here's the code I am using to do this:
if (result.get(CaptureResult.COLOR_CORRECTION_GAINS) != null) {
channelVector = result.get(CaptureResult.COLOR_CORRECTION_GAINS);
}
Anybody else run into this issue and if so... any solutions to it out there???
Consider working with custom Samsung Camera API. These days, it is based on camera2.
Specifically, they provide their COLOR_CORRECTION_GAINS. They also explain that
… the camera device may do additional processing but android.colorCorrection.gains and android.colorCorrection.transform will still be provided by the camera device (in the results) and be roughly correct.
(the emphasis is mine)
By code, I can make a button that inserts these 3 emojis into the text: ⚽️😈🐺
On many phones when the user clicks the button, though, the problem is that ⚽️😈🐺 displays as [X][X][X]. Or even worse, it displays only three empty spaces.
I would like to disable and hide my own built-in emoji-keypad on Android devices that do not display emojis correctly. Does anyone knows or have a tip on how to detect in code if a device has emoji support?
I have read that emoji is supported from android 4.1, but that is not my experience....
I just implemented a solution for this problem myself. The nice thing with Android is that it is open source so that when you come around problems like these, there's a good chance you can find an approach to help you.
In the Android Open Source Project, you can find a method where they use Paint.hasGlyph to detect whether a font exists for a given emoji. However, as this method is not available before API 23, they also do test renders and compare the result against the width of 'tofu' (the [x] character you mention in your post.)
There are some other failings with this approach, but it should be enough to get you started.
Google source:
https://android.googlesource.com/platform/packages/inputmethods/LatinIME/+/master/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategory.java#441
https://android.googlesource.com/platform/packages/inputmethods/LatinIME/+/master/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
Based on Jason Gore answer:
For example create boolean canShowFlagEmoji:
private static boolean canShowFlagEmoji() {
Paint paint = new Paint();
String switzerland = "\uD83C\uDDE8\uD83C\uDDED"; // Here enter Surrogates of Emoji
try {
return paint.hasGlyph(switzerland);
} catch (NoSuchMethodError e) {
// Compare display width of single-codepoint emoji to width of flag emoji to determine
// whether flag is rendered as single glyph or two adjacent regional indicator symbols.
float flagWidth = paint.measureText(switzerland);
float standardWidth = paint.measureText("\uD83D\uDC27"); // U+1F427 Penguin
return flagWidth < standardWidth * 1.25;
// This assumes that a valid glyph for the flag emoji must be less than 1.25 times
// the width of the penguin.
}
}
And then in code whenever when you need to check if emoji is available:
if (canShowFlagEmoji()){
// Code when FlagEmoji is available
} else {
// And when not
}
Surrogates of emoji you can get here, when you click on detail.
An alternative option might be to include the Android "Emoji Compatibility" library, which would detect and add any required Emoji characters to apps running on Android 4.4 (API 19) and later: https://developer.android.com/topic/libraries/support-library/preview/emoji-compat.html
final Paint paint = new Paint();
final boolean isEmojiRendered;
if (VERSION.SDK_INT >= VERSION_CODES.M) {
isEmojiRendered = paint.hasGlyph(emoji);
}
else{
isEmojiRendered = paint.measureText(emoji) > 7;
}
The width > 7 part is particularly hacky, I would expect the value to be 0.0 for non-renderable emoji, but across a few devices, I found that the value actually ranged around 3.0 to 6.0 for non-renderable, and 12.0 to 15.0 for renderable. Your results may vary so you might want to test that. I believe the font size also has an effect on the output of measureText() so keep that in mind.
The second part was answerd by RogueBaneling here how can I check if my device is capable to render Emoji images correctly?
After implementing the camera2 API for the inApp camera I noticed that on Samsung devices the images appear blurry. After searching about that I found the Sasmung Camera SDK (http://developer.samsung.com/galaxy#camera). So after implementing the SDK on Samsung Galaxy S7 the images are fine now, but on Galaxy S6 they are still blurry. Someone experienced those kind of issues with Samsung devices?
EDIT:
To complement #rcsumners comment. I am setting autofocus by using
mPreviewBuilder.set(SCaptureRequest.CONTROL_AF_TRIGGER, SCaptureRequest.CONTROL_AF_TRIGGER_START);
mSCameraSession.capture(mPreviewBuilder.build(), new SCameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureCompleted(SCameraCaptureSession session, SCaptureRequest request, STotalCaptureResult result) {
isAFTriggered = true;
}
}, mBackgroundHandler);
It is a long exposure image where the use has to take an image of a static non moving object. For this I am using the CONTROL_AF_MODE_MACRO
mCaptureBuilder.set(SCaptureRequest.CONTROL_AF_MODE, SCaptureRequest.CONTROL_AF_MODE_MACRO);
and also I am enabling auto flash if it is available
requestBuilder.set(SCaptureRequest.CONTROL_AE_MODE,
SCaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
I am not really an expert in this API, I mostly followed the SDK example app.
There could be a number of issues causing this problem. One prominent one is the dimensions of your output image
I ran Camera2 API and the preview is clear, but the output was quite blurry
val characteristics: CameraCharacteristics? = cameraManager.getCameraCharacteristics(cameraId)
val size = characteristics?.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)?.getOutputSizes(ImageFormat.JPEG) // The issue
val width = imageDimension.width
val height = imageDimension.height
if (size != null) {
width = size[0].width; height = size[0].height
}
val imageReader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 5)
The code below was returning a dimension about 245*144 which was way to small to be sent to the image reader. Some how the output was stretching the image making it end up been blurry. Therefore I removed this line below.
val size = characteristics?.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)?.getOutputSizes(ImageFormat.JPEG) // this was returning a small
Setting the width and height manually resolved the issue.
You're setting the AF trigger for one frame, but then are you waiting for AF to complete? For AF_MODE_MACRO (are you verifying the device lists support for this AF mode?) you need to wait for AF_STATE_FOCUSED_LOCKED before the image is guaranteed to be stable and sharp. (You may also receive NOT_FOCUSED_LOCKED if the AF algorithm can't reach sharp focus, which could be because the object is just too close for the lens, or the scene is too confusing)
On most modern devices, it's recommended to use CONTINUOUS_PICTURE and not worry about AF triggering unless you really want to lock focus for some time period. In that mode, the device will continuously try to focus to the best of its ability. I'm not sure all that many devices support MACRO, to begin with.
SO
There is an API for that: Camera.Parameters.html#getSupportedColorEffects
But it doesn't properly work on my Samsung Galaxy S Plus. It returns 9 color effects, but actually supported only three of them.
I came to that conclusion after launching the 'native' camera app - there are only threee effects available there (sepia, negative and black'n'white). And these work in my application. When I try to apply others form that list that is returned by getSupportedColorEffects() - nothing happens.
Does anybody know how it is possible to find supported color effects?
Here is how I am getting those effects:
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters parameters = mCamera.getParameters();
List<Size> sizes = parameters.getSupportedPreviewSizes();
List<String> effects = parameters.getSupportedColorEffects();
//...
}
I think you may have found a bug in Android, or at least the build of it on that device. It sounds like someone else had a similar issue on a different device: android camera samsung galaxy i9003 setParameters faild.
One thought as a possible workaround: Are you able to successfully set the color effects that aren't working? That is, do you check that getColorEffect() is not null after calling setColorEffect()? If you get null for the ones that don't work, you can just follow up your getSupportedColorEffects() with a loop to verify each.
If that doesn't work, but rather the device is claiming to support effects that it silently ignores, then I'm not sure there's anything you can do about it.