Dynamically resizing images using MediaQuery in Flutter - flutter

I have two pictures of different dimensions meant to be rendered as per the screen size of the phone the app is being run on which I suppose is something that can be achieved using MediaQuery in the following way:
if(MediaQuery.of(context).size.height < initialSize) {
return Image.asset('Image meant for smaller screens')
} else {
return Image.asset('Image meant for bigger screens')
}
What I don't understand is what initialSize value I should be putting in to check and resize accordingly? Hope I have been able to make my question clear!

initialSize differentiate the small image and large image screen based on screen height.
Let say if device's height is less than 200px we want to show X image, else show Y image.
Image getImage() {
if (MediaQuery.of(context).size.height < 200) {
return Image.asset('Image meant for smaller screens');
} else {
return Image.asset('Image meant for bigger screens');
}
}
You need to choose how you like to define small and large screen image, like here 200, initialSize.

Related

Cropping an image in flutter

So I've been trying really hard to crop an image according to my needs in flutter.
Problem statement:
I have a screen and in that screen I show a frame while the device camera is run on the background. Now, what I want is that whenever the user clicks a photo, only the area of that image inside the frame should be kept and rest should be cropped.
What I have done so far?
Added a package image 3.1.3
Wrote code to fetch x,y coordinates of my frame.
Using the calculated x,y coordinates and copyCrop method from the Image package to crop the clicked image.
Now the problem is that I do not know how copyCrop works and the code right now does not give me the expected results.
final GlobalKey _key = GlobalKey();
void _getOffset(GlobalKey key) {
RenderBox? box = key.currentContext?.findRenderObject() as RenderBox?;
Offset? position = box?.localToGlobal(Offset.zero);
if (position != null) {
setState(() {
_x = position.dx;
_y = position.dy;
});
}
}
I assign this _key to my Image.file(srcToFrameImage) and the function above yields 10, 289.125
Here 10 is the offset from x and 289.125 is the offset from y. I used this tutorial for the same.
Code to crop my image using the Image package:
var bytes = await File(pictureFile!.path).readAsBytes();
img.Image src = img.decodeImage(bytes)!;
img.Image destImage = img.copyCrop(
src, _x!.toInt(), _y!.toInt(), src.width, src.height);
var jpg = img.encodeJpg(destImage);
await File(pictureFile!.path).writeAsBytes(jpg);
bloc.addFrontImage(File(pictureFile!.path));
Now, can anyone tell me how i can do this effectively? Right now, it does crop my image but not as I want it to be. It would be really great if someone could tell me how does copyCrop work and what is the meaning of all these different parameters that we pass into it.
Any help would be appreciated.
Edit:
Now, as you can see, i only want the image between this frame to be kept after being captured and rest to be cropped off.

How to resize an image in flutter with conditional statements

I achieved to resize my images using the package image
What I want to achieve is a conditional statement that reduces the size of the image if image is > than max (1920) and dont resize it otherwise.
This is my code:
Widget build(BuildContext context) {
void uploadImage(File result) async {
var image = decodeImage(result.readAsBytesSync());
var thumbnail = copyResize(image, width: 1920);
var encoded = base64.encode(encodeJpg(thumbnail));
var userAccount =
await context.api.customersApi.accounts.uploadProfileImage(defaultOrganisationId, context.blocs.auth.state.user.id, ImageUploadRequest(encoded));
// update the current user
context.blocs.auth.updateUserAccount(userAccount.data);
}
You can check the width and height of the image:
if (image.width > 1920 || image.height > 1920) {
thumbnail = copyResze(image, width: 1920, height: 1920);
}
else {
thumbnail = image;
}
I'm assuming you care mostly about the file size (~ area) of the image, though you should have no problem changing it to look at only one coordinate.
I might also note that a 1920 pixels wide image no longer qualifies as a thumbnail in my opinion, that's as wide as my entire screen.
From the Docs,
I think you can use both height and width property.
Here it like, image.height and image.width.
Hope that works!

Display loaded UI Image in Container with native size

I want to display UI logo images in their aspect ratio but in proper size that fit within its container. Already all logo images as per aspect ratio but few are too big or small compare to requirements.
At present this kind of thing happening:
Here is the code that I am using:
private void ShowGamePlayLogoViewed ()
{
for (int i = 0; i < DataCollection.companyDetailsList.Count; i++) {
Company company = DataCollection.companyDetailsList [i];
if (company.ViewedCounter > 0) {
GameObject companyItemObj = Instantiate (companyItemPref, gridViewContainer) as GameObject;
CompanyItem companyItem = companyItemObj.GetComponent<CompanyItem> ();
companyItem.companyId = company.CompanyId;
companyItem.UpdateCompanyLogo (company.CompanyLogo);
companyItem.UpdateCompanyName (company.CompanyName);
}
}
}
public void UpdateCompanyLogo (Sprite logoSprite)
{
logoImage.sprite = logoSprite;
logoImage.SetNativeSize ();
}
As you are seeing, logos overlapping the container. I want to display properly them in their respective containers also in aspect ratio too.
Let me clarify one more thing: all logos loaded from web server and they all are dynamic at a time, based on server data it will appear in mobile screen.
I have found solution through Unity Forum and I want to say thanks to #Hosnkobf for reply.
Here is the exact reply that worked for me properly:
adjust the image game object inside unity so that it has the height you are looking for. also adjust the anchors so that it scales with different resolutions properly.
Add an "AspectRatioFitter" component to the object. Make it "Height controls width".
Instead of logoImage.SetNativeSize (); do the following:
float aspectRatio = logoSprite.rect.width / logoSprite.rect.height;
var fitter = logoImage.GetComponent<UnityEngine.UI.AspectRatioFitter>();
fitter.aspectRatio = aspectRatio;
I hope this become useful to other members :)

crop variant with aspect ratio 1:1 don't generate square image using fluid viewhelper

I have defined two crop variants “default” and “isotope”. The “default” contains some basic aspect rations like 1:1, 3:4, 16:9 and so on. The “isotope” variant only contains one aspect ratio 1:1, which is also defined as default (selectedRatio = 1:1). In my case, this definition is done by PageTS, which looks like this:
TCEFORM.sys_file_reference.crop.config.cropVariants {
default {
title = Default desktop
selectedRatio = NaN
allowedAspectRatios {
NaN {
title = Frei
value = 0.0
}
1:1 {
title = 1:1
value = 1.0
}
3:2 {
title = 3:2
value = 1.5
}
2:3 {
title = 2:3
value = 0.6666666667
}
4:3 {
title = 4:3
value = 1.3333333333
}
3:4 {
title = 3:4
value = 0.75
}
16:9 {
title = 16:9
value = 1.7777777778
}
}
}
isotope {
title = Auswahl für Isotope Plugin
selectedRatio = 1:1
allowedAspectRatios {
1:1 {
title = 1:1
value = 1.0
}
}
}
}
After adding this piece of code, the variants appears in all places, where file references can be defined, like inside e.g. news records (from news extension).
Now, after adding an image to a news record and clicking on the image manipulation button, I can select the new defined “isotope” crop variant and choose the desired 1:1 (square) crop area. So far so good.
My problem is now, that I don’t get the right output, when using this crop variant inside my fluid template using the the standard image viewhelper from TYPO3.
This:
<f:image image="{image}" cropVariant="isotope" maxWidth="400" />
don't generates square images, which I would expect.
If the source image has an aspect ratio of 4:3, I get flat-pressed rectangles, if the source image has an aspect ratio of 3:4, I get sky scrapers.
I also tried every possible combination of min/max/width/height attributes with/without additional "c", with no luck.
Sometime the result looks better for 4:3 source images, sometime for 3:4 images.
But I could no found a solution to get square (cropped) images for all kind of aspect ratios
[EDIT 04.07.2017]
Further experiments show different behaviors with different types of source image formats.
If the images are jpgs, I must set width="400c" and height="400c" to get square images. If the source images are pngs, a simple maxWidth="400" together with the cropVariant="isotope" do the job. Gif-Images seems to follow there own laws, which I have not yet looked through.
[EDIT 08.07.2017]
My current experience, after building an extension to test hundred of possible combinations: gif cropping is currently not working like expected.
To make things worse, the generated gif images are displayed differently in different browsers.
An example is this generated image:
View this image in FF, Chrome, Safari to see the different

LIBGDX - Image Button - join images

I am trying to use de Image Button on LIBGDX to create a button based on two images.
Using add to second image, works fine, but have one problem.
The images are of different sizes.
Note: I am testing with the same picture to see the result
Is there a way to correct this? Using some scale to the images?
levelsTexture = new Texture(Gdx.files.internal("level1.png"));
levels = new TextureRegion(levelsTexture).split(TILE_WIDTH, TILE_HEIGHT);
ImageButton levels_image = new ImageButton(new TextureRegionDrawable(new
TextureRegion(levels[0][0])));
levels_image.add(new Image (levels[0][0]));
stage.addActor(levels_image);
levels_image.setScale(2f);
The problem:
ImageButton is an extension of the Table class and typically the ImageButton images are set as the background. Using the "add" method for the second image like you did might work kind of, but it behaves differently than setting the background and it also might not be what you want if you want the the second image to also change when you click the button.
The easiest way to add two images to a single ImageButton would be to simply combine the two images in Photoshop (or equivalent) and use that single image on the ImageButton.
The more advanced (and more flexible) method would be to combine the two images programmatically and use this as the background for your ImageButton. This can be done by creating a custom class which extends BaseDrawable and have it take two Images in the constructor. If you want your images stacked on top of each other, set the minHeight of your custom drawable class to be the combined height of your two images. Then override the draw method and draw your two images on top of each other like this:
#Override
public void draw(Batch batch, float x, float y, float width, float height){
img1.getDrawable().draw(batch, x, y, img1.getWidth(), img1.getHeight());
img2.getDrawable().draw(batch, x, y+img1.getHeight(), img2.getWidth(), img2.getHeight());
}
}
The ImageButton takes a Drawable in its constructor, so you can pass this object right into the button when you create it and both of your Images should appear in the button and they will be treated as one.
I've done something similar to make a background for a table using multiple Images and this method works great.
I wrote my own SpriteButton class in which I implement this method for scaling my textures.
private Dimension getScaledDimension(Dimension imgSize, Dimension boundary) {
int original_width = imgSize.width;
int original_height = imgSize.height;
int bound_width = boundary.width;
int bound_height = boundary.height;
int new_width = original_width;
int new_height = original_height;
// first check if we need to scale width
if (original_width > bound_width) {
//scale width to fit
new_width = bound_width;
//scale height to maintain aspect ratio
new_height = (new_width * original_height) / original_width;
}
// then check if we need to scale even with the new height
if (new_height > bound_height) {
//scale height to fit instead
new_height = bound_height;
//scale width to maintain aspect ratio
new_width = (new_height * original_width) / original_height;
}
return new Dimension(new_width, new_height);
}
Then finally you draw the texture with the output dimension as as size to draw.
sb.begin();
sb.draw(this.texture2, this.x, this.y, dim_size_new.width, dim_size_new.height);
sb.end();
So you could technically draw the second image to the size of the the first image, if the first image size is correct.
Your implementation will look different from mine but you should be able to figure it out form here on out.