What's the difference between AssetImage and ExactAssetImage? - flutter

I am unable to understand the difference between AssetImage and ExactAssetImage. I can use
Image(
image: AssetImage(chocolateImage),
)
Or
Image(
image: ExactAssetImage(chocolateImage),
)
with no performance or memory difference. The only advantage ExactAssetImage has is the scale property, but is that all there to it? If yes, then what's the need of AssetImage?

This is related to the images with different pixel densities you provide in your assets list.
I mean when you have provided images like this:
icons/heart.png
icons/1.5x/heart.png
icons/2.0x/heart.png
If you use AssetImage, flutter will choose between your 3 images depending on the device density pixels.
On a device with a 1.0 device pixel ratio, the image chosen would be
heart.png; on a device with a 1.3 device pixel ratio, the image chosen
would be 1.5x/heart.png.
If you use ExactAssetImage, you select the scale manually, doing somthing like:
Image(image: ExactAssetImage("your-asset",scale: 2)),

AssetImage
AssetImage fetches the image from the AssetBundle then uses the context to determine the exact image to use. Then based on the device pixel ratio and size determines the best configuration for the image this then get passed to resolve
ExactAssetImage
ExactAssetImage fetches images in a similar way while also associating a scale with the image. ExactAssetImage ignores the devices pixels ratio and size in the configuration passed to resolve.
In Conclusion
AssetImage is resolution-aware and can pick the right image based on the right device pixel ratio and size while ExactAssetImage is not. So to more directly answer your question ExactAssetImage gives you more control of memory usage as it will use the exact resolution of the image.

Related

What is the use of logical pixel in flutter?

I am not interested in inside workings of logical pixels, I just want to know if flutter automatically use logical pixel
Container(
width:100,
child:...
)
Does flutter uses 100 pixel or logical pixel as width here, I can't figure it out.
You can print screen width
double kScreenWidth(BuildContext ctx) => MediaQuery.of(ctx).size.width;
you can see what it is like
Container(width: 100, ...)
logical pixels
So obvious,
What you see is what you got.
Flutter follows a simple density-based format like iOS. Assets might be 1.0x, 2.0x, 3.0x, or any other multiplier.
Flutter doesn’t have dps but there are logical pixels, which are basically the same as device-independent pixels. The so-called devicePixelRatio expresses the ratio of physical pixels in a single logical pixel.
from flutter dev doc

Images being upscaled in Flutter

I have images stored as blobs in SQLite. Other tools like DB Browser for SQLite show the images themselves are not upscaled.
I scaled them down from an original image with the following code.
final thumbnailData = encodeJpg(copyResize(
decodeImage(imageData),
width: 400,
interpolation: Interpolation.average
));
When displayed in Flutter they are noticably upscaled.
#override
Widget build(BuildContext context) {
return Image.memory(_getThumbnailData());
}
Image.memory() has a scale argument that defaults to 1.0. Setting it manually to be sure doesn't help either.
I have to set it to some guesstimated value like 2.0 to get the correct scale but I don't understand why and wether 2.0 is actually "unscaled" or still slightly off.
How can I tell Flutter to display the images as they are?
Flutter uses logical pixel instead of physical pixels.
Device pixels are also referred to as physical pixels. Logical pixels are also referred to as device-independent or resolution-independent pixels.
How to convert between physical pixels and logical pixels?
To convert between physical pixels and logical pixels, you can use devicePixelRatio.
The number of device pixels for each logical pixel. This number might not be a power of two. Indeed, it might not even be an integer. For example, the Nexus 6 has a device pixel ratio of 3.5.
MediaQuery.of(context).devicePixelRatio

Resizing command changes image shape

I have to resize image i.e if its dimension is 3456x5184 to 700X700 as my code needs image with less number of pixels otherwise it takes too much time to give results.So, when I use imresize command it changes the dimensions of image but at the same time it changes the shape of image i.e the circle in image which I also need to detect looks like oval instead of being cirle. I need your suggestions to resolve this problem. I am really grateful to you people.
Resizing images is done by either subsampling (to get smaller images) or some kind of interpolation (to get larger images)
Input is either a factor or a final dimension for width and height.
The only way to fit a rectangle into a square by simply resizing it is to use different scales for width and height. Which of course will yield in a distorted image.
To achieve what you want you can either crop a 700x700 region from your image or resize image using the same factor for with and height. Then you can fit the larger dimension into 700 and fill the rest around the other dimension with black or whatever you prefer.

Scaling while conserving ration

Upon using the convert method, I would like to be able to transform a landscape or portrait image given the height and width specify without altering the ratio.
From the documentation, the 'clip' options act as follow:
'clip': Resizes the image to fit within the specified parameters without distorting, cropping, or changing the aspect ratio
If I have a 200x50 image and I want a 150x150 result, this would result in a 150x37px resized image with its ratio identical to the original's.
If I have a 100x50 image and I want a 150x150 result, this would result in a 150x75px resized image with its ratio identical to the original's.
'crop': Resizes the image to fit the specified parameters exactly by removing any parts of the image that don't fit within the
boundaries
If I have a 200x50 image and I want a 150x150 result, this would result in a 150x37px cropped image.
'scale': Resizes the image to fit the specified parameters exactly by scaling the image to the desired size
If I have a 200x50 image and I want a 150x150 result, this would result in a 150x150px resized image where the ratio has been altered to fit.
'max': Resizes the image to fit within the parameters, but as opposed to 'clip' will not scale the image if the image is smaller
than the output size
Same output as in 'clip' except that if I have a 100x50 image and I want a 150x150 result, this would result in a 100x50px resized image with its ratio identical to the original's.
What I would like to have is the ability to make an image conserve its ratio and be of the required dimension (with vertical and horizontal centering if need be). It would result in an image that is not distorted nor clipped.
I understand there are some trickiness to the task as you have to determine what color do you fill the space with (see ImageMagick doc about space filling).
Any insight would be great, hope it is not too much of an edge case.
Take a look at this set of examples in the ImageMagick documentation:
http://www.imagemagick.org/Usage/thumbnails/#square
We don't currently offer the ability to "fill" empty parts of the image with a background color, so do not support this use case. We are looking at adding it in the near term, and will update you when this is added.

Difference between stretching and scaling an image

Can anybody please tell me what is the exact difference between stretching and scaling an image? Because you can anyway set the size of image and imageView both to match your requirements.
It depends on how you define stretching, but I would divide scaling into two distinct options based on whether or not the aspect ratio is preserved. Often it is desired to preserve the aspect ratio when scaling an image.
I would consider an increase in one dimension, but not proportionally in the other to be a "stretch". Similarly, a decrease in one dimension, but not proportionally in the other would be a "squash".
You may find this Daring Fireball post interesting.
Stretching sounds like showing small size (10x10) image at (100x100) or (100x10). so some times it gets pix-elated.
And scaling means to show a image to different size either small or big with maintaining its aspect ratio (programmetically), so it will look not improper, because when you stretch to different aspect ratio then some objects in image gets improper visibility.
Stretching (in iphone IB) means '9-slice scaling', scaling means just scaling.
When stretching you can determine which part of the image may be used for stretching and which part may not. For example when you have a rounded square, you do not want the roundings to stretch, especially when you're only stretching horizontally or vertically.
You indicate that you only want to use the middle pixel to stretch by (in IB) setting the X & Y values to 0.50 (half way) and the width & height values to 0.00 (minimum amount of pixels)
Lookup contentStretch in the docs for more info
when you don,t keep the congruence of your image, you see the image incongruous and height and width of your image is not suitable for showing. for resolving this issue you can multiply your image's width and height to to a constant coefficient.
Stretching and scaling don't mean anything different except maybe in connotation.
Is there a particular piece of text somewhere that you are trying to understand? Maybe we can help with that.
stretching image is stretching the size of a small image.
on the other hand scaling of image is scaling the image accoring the the viewport's width and viewport's height....
scaling can be done by small as well as large image.
you should take a good quality image and then should scale it
sprite.setscale(x,y);