Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android rotated texture #9

Closed
eduardhasanaj opened this issue Oct 19, 2017 · 11 comments
Closed

Android rotated texture #9

eduardhasanaj opened this issue Oct 19, 2017 · 11 comments
Labels

Comments

@eduardhasanaj
Copy link

eduardhasanaj commented Oct 19, 2017

Hi,
First of all thank you for providing this amazing plugin as open source.
It works great and fast but from what I see images are rotated 90 degree. How can I fix this?
Best wishes

@eduardhasanaj
Copy link
Author

eduardhasanaj commented Oct 19, 2017

Oh I think II know what s the fix. We need to modify plugin to return also EXIF data.

@thedoritos
Copy link
Owner

Hi, @eduardhasanaj2

Thanks for reporting the issue!
I guess it is the same problem reported on #5, and we're working on in at fix/image_rotation branch.

I changed the code to read EXIF and fix rotation with iOS/Android native code before returning it to the Unity side.

The patch is also available as a package on Release Fix image rotation · thedoritos/unimgpicker.

Try it and please tell us if it worked on your environment.
Then we can merge it into the master!

Thank you.

@eduardhasanaj
Copy link
Author

eduardhasanaj commented Oct 20, 2017

I updated plugins folder, it do not show anything.
By the way i have a working fix but could you please try to understand why my images are cropped
?
Edit fixed we need matrix.setPostRotate
But I see a problem about aspect ratio. I am getting equal width height
Here is the code

                        InputStream inputStream = context.getContentResolver().openInputStream(uri);
			float orientation = getOrientation(inputStream, uri);
			// Decode metadata
			BitmapFactory.Options opts = new BitmapFactory.Options();
			opts.inJustDecodeBounds = true;
			BitmapFactory.decodeStream(inputStream, null, opts);
			inputStream.close();

			// Calc size
			float scaleX = Math.min((float)mMaxSize / opts.outWidth, 1.0f);
			float scaleY = Math.min((float)mMaxSize / opts.outHeight, 1.0f);
			float scale = Math.min(scaleX, scaleY);
			
			float width = opts.outWidth * scale;
			float height = opts.outHeight * scale;

			// Decode image roughly
			inputStream = context.getContentResolver().openInputStream(uri);
			opts = new BitmapFactory.Options();
			opts.inSampleSize = (int)(1.0f / scale);
			Bitmap roughImage = BitmapFactory.decodeStream(inputStream, null, opts);

			// Resize image exactl

			Bitmap image = null;

			if (needsNormalization(orientation))
            {
				Matrix matrix = new Matrix();
				matrix.setRotate(orientation);

                roughImage = Bitmap.createBitmap(roughImage, 0, 0,
						roughImage.getWidth(), roughImage.getHeight(), matrix, true);
            }

			image = Bitmap.createScaledBitmap(roughImage, (int) width, (int) height, true);

			// Output image
			FileOutputStream outputStream = context.openFileOutput(mOutputFileName, Context.MODE_PRIVATE);
			image.compress(Bitmap.CompressFormat.PNG, 100, outputStream);

			outputStream.close();
			inputStream.close();

@thedoritos
Copy link
Owner

About unimgpicker's patch

I updated plugins folder, it do not show anything.

I could not get what happened.

  • The picker failed to return the path to the image you picked?
  • Or you have something wrong with the image at the path?

About your code

It is hard to say anything without the real code.
The only recommendation I came up with is to open a new InputStream instead of reusing the same instance.

InputStream exifStream = context.getContentResolver().openInputStream(uri);
float orientation = getOrientation(exifStream, uri);

InputStream inputStream = context.getContentResolver().openInputStream(uri);

// Decode metadata
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeStream(inputStream, null, opts);

// ...

Thank you.

@eduardhasanaj
Copy link
Author

eduardhasanaj commented Oct 21, 2017

Sorry I didn't watch your post. I tried your version but when I pick it didnt show inn my tablet.
Most probably invalid AspectRatioFitter can cause that. I mean aspent ratio can cause not showing issue.
Exactly InpuStream was the problem. Working great.
Here is the exif Code
Please do you have any device to test the cursor, the second part. It was always returning 0 on Galaxy

private float getOrientation (InputStream image, Uri photoURI) {
		//ExifInterface myExif = new ExifInterface(photoURI.getPath());

		float photoRotation = 0;
		boolean hasRotation = true;

		try {
			ExifInterface exif = new ExifInterface(image);
			int exifRotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
					ExifInterface.ORIENTATION_UNDEFINED);

			switch (exifRotation) {
				case ExifInterface.ORIENTATION_UNDEFINED: {
					hasRotation = false;
				}
				case ExifInterface.ORIENTATION_ROTATE_90: {
					photoRotation = 90.0f;
					break;
				}
				case ExifInterface.ORIENTATION_ROTATE_180: {
					photoRotation = 180.0f;
					break;
				}
				case ExifInterface.ORIENTATION_ROTATE_270: {
					photoRotation = 270.0f;
					break;
				}
			}
		} catch (IOException e) {
		}

		if (!hasRotation) {
			try {
					String[] columns = {MediaStore.Images.Media.DATA, MediaStore.Images.Media.ORIENTATION};
					Cursor cursor = getActivity().getContentResolver().query(photoURI, columns, null, null, null);

					if (cursor == null) return 0;

					if (cursor.moveToFirst()) {
						int orientationColumnIndex = cursor.getColumnIndex(columns[1]);
						photoRotation = cursor.getInt(orientationColumnIndex);
					}
					cursor.close();
			}
			catch (Exception e) {}

		}

		return photoRotation;
	}

@thedoritos
Copy link
Owner

I'm happy to hear that your code worked! :)

Let me get it clear.
Your are using AspectRatioFitter in your Unity app. And my code at fix/image_rotation did not work because the orientation check with the MediaStore query is missing in it.

If so, I want merge the query part into fix/image_rotation branch.
It'll take few days because I don't have much time this week unfortunately.

You can choose to do it your own and send me a pull request to the branch if you want. That's more than welcome.

Thank you.

@eduardhasanaj
Copy link
Author

eduardhasanaj commented Oct 23, 2017

I tried again your code and it worked like charm. I recalled that also the version of plugin modified by me was not displaying nothing due to an error in setting aspect ratio.

Let me get it clear.
Your are using AspectRatioFitter in your Unity app. And my code at fix/image_rotation did not work because the orientation check with the MediaStore query is missing in it.

Nope. Unfortunately I did not see your code in the new version. I was saying that i tried media store query but it didnt work. When i tried it in my code it was returning 0 all the time. I asked you to try to find a device that support it just to test, because some devices do not save exif information so it is needed fallback to cursor.

Unfortunately I just downloaded the project repository as zip so I do not know how to merge it.
It s better if you do it but we need to test if it works on older devices.
Thank you for your support.

@ImThaDude
Copy link

Tested the changes on fix/image_rotation. Retrieved the IOS files from the plugin folder on that branch and tested it on IOS 6 and IOS XS. It fixes the rotation upon creating the png. It works.
Using Unity 2018.4.5f1.

Cheers!

@richardrevesz
Copy link

richardrevesz commented Dec 10, 2020

Hey, thank you for the great tool!
The master works fine, except the fact it ignores the rotation of the image, so I hoped this branch will solve it.
But it is not building on Android, gives me these errors:

Also, I can see at the commit message that there were issues with the jar.
Can you/will you look into it?
Or what is the reason the correct image rotation is not merged into the master?

Thanks mate!
Best,
Richard

@thedoritos
Copy link
Owner

Hi, @richardrevesz. Thx for your feedback!

The v2 implementation on master branch should return the original image file, and it should contain EXIF data. I believe you can read EXIF to get the rotation info of the image. However, I'm not sure it really works on your environment.

BTW, the branch fix/image_rotation was for v1.x, and it is not planned to be updated.

Thank you!

@richardrevesz
Copy link

I see, thank you!

For anyone else looking for how to read EXIF data, check out this repo:
https://github.com/tedbarnett/read-exif-in-unity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants