Imagesharp - prevent from resizing small images - imagesharp

Is it possible to prevent Imagesharp from resizing images if their dimensions are smaller than those specified in the query parameters?

If you mean ImageSharp.Web then yes.
You would have to replace the default ResizeWebProcessor with an updated version of Process(FormattedImage image, ILogger logger, IDictionary<string, string> commands) that first checks the size parsed from the command against the input image.

Related

Meteor mobile-config.js launchScreens

I'm creating the splash images for my app but I've got some questions:
Can I create of all them at once? I've seen some repos for this but
there are not updated with new sizes (e.g 2048x1536)
Would be possible to use the same image for different sizes?
My phone is 1920x1080 but there is no splash screen size for that so it takes one and applies a disproportionate image. If I've got
text on it it looks really badly.
What happens with the rest of images when I build? Meteor removes the rest? Are located in resources/splash.
Could be possible to use a html with css page?
Thanks in advance!
Next time you should consider splitting your questions into independent posts.
Creating splash images: if your image is simple enough, indeed you have many scripts that can generate the different sizes automatically. I am sure you can customize them to fit your sizes.
Use the same image for different sizes: in general, that would mean your image will be stretched by the device to fill the screen. On Android, you can define a 9-patch PNG that will tell the device which pixels can be stretched, so that some part(s) of your image is not deformed.
Deformed image for 1920x1080 screen: depending on the pixel density, there should very probably be a placeholder for that.
Storage of image versions: by default, all versions (i.e. sizes) are packaged within your APK / APP, so that whatever the device needs will be available once user has downloaded the app.
Using an HTML+CSS page for splash screen: in general, no, but it depends on what you want to do with your splash screen. Meteor calls it "launch screen", because it is the first thing it displays while the app is loading / "launching". In particular, the WebView and local server may not be ready yet, and cannot serve any HTML/CSS. That is why you have to use a plain image, which is passed to a very simple activity while the app is loading. But some people also use a "waiting screen" between some parts of their app. In that case, your WebView and local server are already loaded, and you can simply use whatever you want.
Update:
For Android, if 9-patch PNG does not fit your need, you can also try to request Cordova's splashscreen plugin to maintain the aspect ratio of your image:
https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-splashscreen/#preferences
<preference name="SplashMaintainAspectRatio" value="true" />
"SplashMaintainAspectRatio" preference is optional. If set to true, splash screen drawable is not stretched to fit screen, but instead simply "covers" the screen, like CSS "background-size:cover". This is very useful when splash screen images cannot be distorted in any way, for example when they contain scenery or text. This setting works best with images that have large margins (safe areas) that can be safely cropped on screens with different aspect ratios.
In Meteor, you would use App.setPreference in mobile-config.js:
App.setPreference("SplashMaintainAspectRatio", true, "android");

ImageView: animated gif preview

I am putting together an image gallery that displays a preview of the image. For most of the images this is no problem, only when the image is an animated gif the image is animated as well, which in this case is not necessary.
What I would like to do for an animated gif is to just display one frame of the animation.
While searching for a solution I have come across this.
GifDecoder d = new GifDecoder();
d.read( filename);
WritableImage wimg = null;
Image img = SwingFXUtils.toFXImage(d.getFrame(0), wimg);
But first of all this seems to be too much overhead and a quick test so far ended in a NullPointerException due to the fact that d.getFrame(0) returns null.
I was thinking that there must be an easier way, like some property on the Image to avoid animating the image, or as an alternative approach not displaying the image in an ImageView.
There were two reasons the GifDecoder did not work.
The first one was really my mistake, as the String passed to the read method should be an URI:
File f = new File(filename);
d.read(f.toURI().toString());
The second issue lies with the GifDecoder: To check the input URI it is converted to lower case and that converted String is then used to create in InputStream. This works on an OS that is not case sensitive (like Windows) but not on NIX based systems. I therefore had to fix that and now it is working.

Is it possible to specify direction when using the ##images/image/tag url form?

Specifically, the default scaling profile uses the 'keep' scale property; see https://github.com/plone/plone.scale/blob/master/plone/scale/scale.py#L62
This scales without cropping.
It's useful to set the plone.allow_sizes registry key to allow custom tags, eg.
http://192.168.15.156:8080/Plone/media/4qrcrmn.jpg/##images/image/tile
However, this doesn't respect the requested size; it simple proportionally scales the image.
I've been digging through the source of https://github.com/plone/plone.app.imaging/blob/master/src/plone/app/imaging/scaling.py#L179 trying to understand what's happening, but there doesn't appear to be a way to override the direction property here?
Is there some other way of doing this, or is the only option to create custom views for the Image type?
I guess this is not possible simply through the url.
You could either generate a tag inside a view (like you said) and crop it to the exact size you need: https://github.com/plone/plone.app.imaging/blob/master/README.rst#new-style-image-scales
Or you could use plone.app.imagecropping. With this package you can edit each uploaded image and crop it to the exact size you defined in the available scales. You can even specify which area of the image should be used for the crop. After this is done the url
http://192.168.15.156:8080/Plone/media/4qrcrmn.jpg/##images/image/tile
Will give you the exact cropped image you have specified for that scale.

Minimize picture size

I have a picture into JavaFX application which is loaded +30 times into chart. I use this code to load it and shrink the size.
ImageView livePerformIcon = new ImageView(MainApp.class.getResource("/images/Untitledwdwd.png").toExternalForm());
livePerformIcon.setFitHeight(100);
livePerformIcon.setFitWidth(100);
label.setGraphic(livePerformIcon);
Can you tell em how I can optimize this code for performance and memory is there a way to save resources during work.
Maybe livePerformIcon.setCache(true); can solve this?
Load the Image once and use the same Image instance for all the ImageViews. The example in the ImageView javadocs does this.

JavaFX ImageView without any smoothing

Is it possible to render a scaled image in an ImageView in JavaFX 2.2 without any smoothing applied? I'm rendering a 50x50 image into a 200x200 ImageView, with setSmooth(false), so each pixel in the source image should map to a 4x4 square on the screen.
However, the resulting render still smooths the source pixel across all 16 destination pixels. Does anyone know of a way to do this without manually copying over each pixel into a new image?
In JavaFX 2.2 ImageView is always going to do some smoothing regardless of the smooth hint you provide to the ImageView.
(Based on testing using Java 7u15 and Windows 7 with an ATI HD4600 graphics card).
Perhaps it is a bug that ImageView will always smooth the Image, but the documentation doesn't really specify exactly what smoothing does or doesn't do, so it's hard to say what its real intent is. You may want to post a reference to this question to the openjfx-dev mailing list or log an issue in the JavaFX issue tracker to get a more expert opinion from a developer.
I tried a few different methods for scaling the Image:
Scale in the Image constructor.
Scale in ImageView with fitWidth/fitHeight.
Scale by using the scaleX/scaleY properties on an ImageView.
Scale by sampling the Image with a PixelReader and creating a new Image with a PixelWriter.
I found that methods 1 & 4 resulted in a sharp pixelated image as you wish for and 2 & 3 resulted in a blurry aliased image.
Sample code to generate the above output.
Update with ideas on implementing your own image filter
A JavaFX Effect is not the same as the Filter used for the Image loading routines, though an Effect to filter an image could be created. In JavaFX 2.2 publicly documented API to support creation of custom effects, so creating of a custom effect may prove difficult.
The native code for image support was recently open sourced as part of the openjfx project, so you could look at that to see how the filtering is currently implemented.
You may also want to file a feature request against the JavaFX runtime project to "allow us to make our own 2D filters".
I know this is a bit older, but I recently had a need for such ImageView, and the following little hack does exactly what I want on my (Windows) machine. No guarantees that it works everywhere.
import com.sun.javafx.sg.prism.NGImageView;
import com.sun.javafx.sg.prism.NGNode;
import com.sun.prism.Graphics;
import com.sun.prism.Texture;
import com.sun.prism.impl.BaseResourceFactory;
import com.sun.prism.Image;
import javafx.scene.image.ImageView;
#SuppressWarnings("restriction")
public class PixelatedImageView extends ImageView {
#Override protected NGNode impl_createPeer() {
return new NGImageView() {
private Image image;
#Override public void setImage(Object img) {
super.setImage(img);
image = (Image) img;
}
#Override protected void renderContent(Graphics g) {
BaseResourceFactory factory = (BaseResourceFactory) g.getResourceFactory();
Texture tex = factory.getCachedTexture(image, Texture.WrapMode.CLAMP_TO_EDGE);
tex.setLinearFiltering(false);
tex.unlock();
super.renderContent(g);
}
};
}
}
The trick here is that the texture gets re-used, so the linear filtering setting remains "sticky". Why NGImageView couldn't simply pass the "smooth" flag to the texture's linear filtering setting is beyond me however.
No fix for ImageView, but it helped me a lot.
After searching for ages, I stumbled upon this post: How can I disable antialiasing on a JavaFX Canvas?
For drawing the image on a canvas, the smoothing can be disabled since JavaFX 12
canvas.getGraphicsContext2D().setImageSmoothing(false);
When you add the following constructor to Martin Sojka's answer you can simply pass the javafx Image to the constructor. Also despite the warnings about deprecated functions his answer still works fine (on JDK 1.8_121).
public PixelatedImageView (javafx.scene.image.Image image) {
super(image);
}

Resources