How to rotate an image in Glide to be right side up - android

I am a little bit of a novice Android developer but I am working on a project to improve memory efficiency in our app's handling of images.
Right now, we have some code for rotating an image based on the Exif data to ensure that it's right side up. I'd like to do the same thing but in Glide, but I can't find any documentation on that... or even documentation on reading Exif data.
I have to imagine this is a fairly common use case! I'd like to take the following code and reduce it to a straightforward Glide method.
Here's what we have now:
final Matrix bitmapMatrix = new Matrix();
int widthMultiplier = 1;
int heightMultiplier = 1;
try {
Metadata metadata = ImageMetadataReader.readMetadata(new ByteArrayInputStream(bo.toByteArray()));
final Collection<ExifIFD0Directory> exifIFD0Directories = metadata.getDirectoriesOfType(ExifIFD0Directory.class);
if (exifIFD0Directories != null) {
for (ExifIFD0Directory d : exifIFD0Directories) {
if (d.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
try {
final int exifOrientation = d.getInt(ExifIFD0Directory.TAG_ORIENTATION);
switch (exifOrientation) {
case 1:
break; // top left
case 2:
heightMultiplier = -1;
break; // top right
case 3:
bitmapMatrix.postRotate(180);
break; // bottom right
case 4:
bitmapMatrix.postRotate(180);
heightMultiplier = -1;
break; // bottom left
case 5:
bitmapMatrix.postRotate(90);
heightMultiplier = -1;
break; // left top
case 6:
bitmapMatrix.postRotate(90);
break; // right top
case 7:
bitmapMatrix.postRotate(270);
heightMultiplier = -1;
break; // right bottom
case 8:
bitmapMatrix.postRotate(270);
break; // left bottom
default:
break; // Unknown
}
break;
} catch (MetadataException e) {
handleException(e, subscriber, uri, inputStream, mFinalPath, fromGallery);
return;
}
}
}
}
} catch (ImageProcessingException | IOException e) {
handleException(e, subscriber, uri, inputStream, mFinalPath, fromGallery);
return;
}
Any ideas are appreciated.

From some additional resource, it sounds as if Glide actually handles this automatically.

Related

Directional buttons do not work in the "negative" direction

I am trying to make an image view move Up/Down/Left/Right using image buttons. I am able to get the image to move right and down, however up and left do not work.
I have tried changing the +/- sign, the length of the increments to move the image, and also the if/else statements to determine whether or not to move the image.
// Move ImageView Up
case R.id.upBtn: {
if (img.getY() > 0) {
img.setY(img.getY() - 25);
}
}
// Move ImageView Down
case R.id.downBtn: {
if (img.getY() < 950) {
img.setY(img.getY() + 25);
}
}
// Move ImageView Left
case R.id.leftBtn: {
if (img.getX() > 0) {
img.setX(img.getX() - 25);
}
}
// Move ImageView Right
case R.id.rightBtn: {
if (img.getX() < 2000) {
img.setX(img.getX() + 25);
}
}
The image view is supposed to move in all directions but it won't go in the up or left directions. I removed the if/else statements to see if they were the issue and they had no effect in regards to moving the image. They just keep it from going off the screen. It appears that I can not subtract from the getY() function but that does not make sense.
You are missing break statements, so once a case is matched, the code of all following case statements will also execute.
Try :
// Move ImageView Up
case R.id.upBtn: {
if (img.getY() > 0) {
img.setY(img.getY() - 25);
}
}
break;
// Move ImageView Down
case R.id.downBtn: {
if (img.getY() < 950) {
img.setY(img.getY() + 25);
}
}
break;
// Move ImageView Left
case R.id.leftBtn: {
if (img.getX() > 0) {
img.setX(img.getX() - 25);
}
}
break;
// Move ImageView Right
case R.id.rightBtn: {
if (img.getX() < 2000) {
img.setX(img.getX() + 25);
}
}
break;
default :

Change Images or Bitmap when ever touched on screen

I want to change the bitmap that contains an image whenever user tap on the screen. i.e. the default image is shadow1, now what i want is that when user touched on screen then this image changed to shadow2, then again if user touched then shadow3, then on next touch the image again comes as shadow1 and it goes on and on and on. so basically there are three images and i want that when ever user touched on screen then image changes with each tap.
Following is the code that i tried but it is still not working as expected i.e. the image changes from shadow1 to shadow2 but then not changes to shadow3 or shadow1 even if i touched many times.
public void Touched(float x, float y)
{
boom = false;
try{
switch (bird.GetState()) {
case 0:
distance = 0;
bird.SetState(1);
flapped = true;
Bitmap workingBitmap = BitmapFactory.decodeResource(gameLogic.Resources(), R.drawable.shadow1);
bitmapBird = workingBitmap.copy(Bitmap.Config.ARGB_8888, false);
if (bitmapBird==workingBitmap)
{
}
riseCounter = 0;
pipeValues.clear();
//SoundManager.playSound(2, 1);
break;
case 1:
{
riseCounter = 0;
flapped = true;
t = 3;
Bitmap workingBitmappp = BitmapFactory.decodeResource(gameLogic.Resources(), R.drawable.shadow2);
bitmapBird = workingBitmappp.copy(Bitmap.Config.ARGB_8888, false);
//SoundManager.playSound(2, 1);
}
break;
case 2:
{
riseCounter = 0;
flapped = true;
t = 0;
}
break;
default:
Bitmap workingBitma = BitmapFactory.decodeResource(gameLogic.Resources(), R.drawable.shadow3);
bitmapBird = workingBitma.copy(Bitmap.Config.ARGB_8888, false);
break;
}
} catch(Exception e){}
}
I think there should be a for loop or while loop in 'case 1' and whenever user tap then image changes. Please help me with this.
You can simply use an int value to keep track of the image displayed as;
First Initialize a int at class level;
int num = 0;
then you can use it as;
if(num == 0){
loadFirstImage();
num++;
}
else if(num == 1)
{
loadSecondImage();
num++;
}
else if(num == 2){
loadThirdImage();
num = 0 ;
}
I think that you need to change the state of the bird in your second case statement.
First iteration will set the state to 1, from there, the only case statement you can hit is case 1: because you never change it.
So you need something like
case 1:
bird.SetState(2);
//....
Hope that helps

Image is getting rotated when clicked from camera only in Samasung device

In my application Image is getting rotated when it is clicked from camera in portrait mode, this happens only for samsung device and for the rest it works fine. I implemented following code after researching in stack overflow:
ExifInterface ei = new ExifInterface(imgFile.getPath());
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
switch (orientation) {
case ExifInterface.ORIENTATION_UNDEFINED:
mBitmap = rotateImage(bitmap, 90);
break;
}
This code helps me to fix that issue in samsung but now when image is clicked from camera it is getting rotated in other devices due to this piece of code.
Please let me know how can I fix this issue.
pass that return degrees to convert the bitmap,
try {
ExifInterface exif = new ExifInterface(imgPath);
String rotationAmount = exif
.getAttribute(ExifInterface.TAG_ORIENTATION);
if (!TextUtils.isEmpty(rotationAmount)) {
int rotationParam = Integer.parseInt(rotationAmount);
switch (rotationParam) {
case ExifInterface.ORIENTATION_NORMAL:
return 0;
case ExifInterface.ORIENTATION_ROTATE_90:
return 90;
case ExifInterface.ORIENTATION_ROTATE_180:
return 180;
case ExifInterface.ORIENTATION_ROTATE_270:
return 270;
default:
return 0;
}
} else {
return 0;
}
} catch (Exception ex) {
return 0;
}
If you are confident that this is only Samsung device issue, you can check for the device make and add that to your if(...) condition. This library can be of great help.
Also have a look at Jared Rummler's answer to this question:
But if this is a device specific issue, it may occur on other devices too or may be eventually corrected in newer Samsung device OS updates. Keep a good check on that.

How to change position of a moving body - Box2D

I currently have a body created that is Dynamic and moves at a constant speed with a Vector2(). What I want is for when the body leaves the edge of the screen, to come back from that current point back to its original point instantaneously. How do I do this?
a.applyForceToCenter(aMovement, true);
a.applyTorque(3000, true);
FixtureDef fDef = new FixtureDef();
BodyDef ballD = new BodyDef();
ballD.type = BodyType.DynamicBody;
//random location for asteroid
int aLoc = (int) (aLocation * 15);
float x = 300;
switch(aLoc)
{
case 0:
ballD.position.set(x, -105);
break;
case 1:
ballD.position.set(x, -95);
break;
case 2:
ballD.position.set(x, -80);
break;
case 3:
ballD.position.set(x, -65);
break;
case 4:
ballD.position.set(x, -50);
break;
case 5:
ballD.position.set(x, -35);
break;
case 6:
ballD.position.set(x, -20);
break;
case 7:
ballD.position.set(x, -5);
break;
case 8:
ballD.position.set(x, 10);
break;
case 9:
ballD.position.set(x, 25);
break;
case 10:
ballD.position.set(x, 40);
break;
case 11:
ballD.position.set(x, 55);
break;
case 12:
ballD.position.set(x, 70);
break;
case 13:
ballD.position.set(x, 85);
break;
default:
ballD.position.set(x, 0);
}
PolygonShape asteroid = new PolygonShape();
asteroid.setAsBox(12.5f, 12.5f);
//asteroid definition
fDef.shape = asteroid;
fDef.density = .5f;
fDef.friction = .25f;
fDef.restitution = .75f;
a = world.createBody(ballD);
a.createFixture(fDef);
a.setFixedRotation(false);
//asteroid image
aSprite = new Sprite(new Texture("img/asteroid-icon.png"));
aSprite.setSize(12.5f * 4, 12.5f * 4);
aSprite.setOrigin(aSprite.getWidth() / 2, aSprite.getHeight() / 2);
a.setUserData(aSprite);
asteroid.dispose();
You could use Body.setTransform() for that task, but I would not do that. setTransform() causes a lot of trouble in the long run.
For me it lead to weird bugs. For example using setTransform disabled my ContactFilter in random moments, which cost me several days of debugging until I found that.
Furthermore it causes non-physical behaviour, because you basically teleport the Body.
Better would be to destroy the Body completely and recreate a new one at the same initial position of the old one.
You can set the position of your Box2D a body instantly through this method:
a.setTransform(new_x, new_y, new_angle);
With this, you can create a condition that sets the x and y position of the body back to its original position when the x or y value of the body is outside of the screen.
if(outsideBounds()){
a.setTransform(start_x, start_y, start_angle);
}
You can check whether your object is offscreen by either checking its Box2D position and its converted screen coordinates, or by checking the sprite's location.
Once you've received the x and y screen positions, you can compare them to the screen bounds like this:
pos_x>screenWidth||pos_x<0||pos_y>screenHeight||pos_y<0
This can be improved by including the dimensions of the object, depending on when you want the transformation to happen:
(pos_x-objWidth)>screenWidth || (pos_x+objWidth)<0 ||
(pos_y-objHeight)>screenHeight || (pos_y+objHeight)<0
You can use the following:
body.setTransform(newX, newY, newAngle);
body.setAwake(true);
Waking up the body is important.
It might be currently inactive and without waking it up neither gravity nor any immediate collisions will affect it at the new position.

Detect Android orientation: landscape-Left v. landscape-Right

How can I detect which one of 4 sides of the phone is up.
I can detect portrait/landscape mode, but how do I tell landscape-turned-on-left-side from landscape-turned-on-right-side?
Basically I want to make a nice transition animation when user turns phone. You know, like in iPhone's Safari: a swift 400ms rotation from the previous layout to the new.
Use an OrientationEventListener:
mOrientationEventListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL)
{
#Override
public void onOrientationChanged(int orientation)
{
mDeviceOrientation = orientation;
}
};
if(mOrientationEventListener.canDetectOrientation())
{
mOrientationEventListener.enable();
}
mDeviceOrientation should then be an integer telling you the angle your device is rotated to, if you do some clever rounding you should be able to see which of the four orientations it is in:
// Divide by 90 into an int to round, then multiply out to one of 5 positions, either 0,90,180,270,360.
int orientation = 90*Math.round(mDeviceOrientation / 90);
// Convert 360 to 0
if(orientation == 360)
{
orientation = 0;
}
Enjoy!
Just came across :) 2.2+ put xml code to ur res/values(false) and res/values-xlarge(true)
<resources>
<bool name="isTablet">false</bool>
private void getScreenRotationOnPhone() {
final Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
switch (display.getRotation()) {
case Surface.ROTATION_0:
System.out.println("SCREEN_ORIENTATION_PORTRAIT");
break;
case Surface.ROTATION_90:
System.out.println("SCREEN_ORIENTATION_LANDSCAPE");
break;
case Surface.ROTATION_180:
System.out.println("SCREEN_ORIENTATION_REVERSE_PORTRAIT");
break;
case Surface.ROTATION_270:
System.out.println("SCREEN_ORIENTATION_REVERSE_LANDSCAPE");
break;
}
}
private void getScreenRotationOnTablet() {
final Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
switch (display.getRotation()) {
case Surface.ROTATION_0:
System.out.println("SCREEN_ORIENTATION_LANDSCAPE");
break;
case Surface.ROTATION_90:
System.out.println("SCREEN_ORIENTATION_REVERSE_PORTRAIT");
break;
case Surface.ROTATION_180:
System.out.println("SCREEN_ORIENTATION_REVERSE_LANDSCAPE");
break;
case Surface.ROTATION_270:
System.out.println("SCREEN_ORIENTATION_PORTRAIT");
break;
}
}
private boolean isTabletDevice(){
boolean tabletSize = getResources().getBoolean(R.bool.isTablet);
if (tabletSize) {
return true;
} else {
return false;
}
}
It seems like you should be able to tell from the screenOrientation, gotten via getRequestedOrientation
I was able to get landscape left vs right events using this code:
object : OrientationEventListener(this, SENSOR_DELAY_NORMAL) {
override fun onOrientationChanged(orientation: Int) {
afterGlobalLayout {
logInfoToast(if (screenRotation == LandscapeLeft)
"LandscapeLeft" else "LandscapeRight")
}
}
}.enable()
afterGlobalLayout uses viewTreeObserver.addOnGlobalLayoutListener
and screenRotation is calculated by Piotr Ĺšlesarew code.

Categories

Resources