Xamarin SKEncodedImageFormat Jpeg background added - xamarin

I'm coding in Xamarin with SkiaSharp libraries for UWP (eventuallay Android but not ios) with VS 2019
With this code
SKBitmap signature = SKBitmap.Decode(canvasImg.Encode());
using (var image = SKImage.FromBitmap(signature))
using (var data = image.Encode(SKEncodedImageFormat.Jpeg, 80))
{
// Save data to a stream
using (var streamSign = File.OpenWrite(Path.Combine(PCLStorage.FileSystem.Current.LocalStorage.Path + "\\work\\Models", "signature.jpg")))
{
data.SaveTo(streamSign);
}
}
I get a jpg file of my canvas. This is working perfectly. The issue is the image format defined with this line:
SKEncodedImageFormat.Jpeg
I need jpg format (and absolutely not png). The issue is this converter add me a black background and the black draws are invisible.
Anyone know how can i set the background added white ?

There are two possible workarounds
Convert the image to Png type and add a transparent background on it .
Refer to Adding transparency to a SKBitmap image results in black background .
Since there is no option of Jpg for SKEncodedImageFormat , we could use external tools(like paint , photoshop) to transfer the image to Png or Jpeg type .
Refer to https://social.msdn.microsoft.com/Forums/en-US/b466c566-6666-4cc9-9cdc-88d8c0032e2b/adding-transparency-to-a-skbitmap-image-results-in-black-background?forum=xamarinlibraries

Related

Unity - sprites take up more memory than textures? Causes a black screen after launch on device?

I have a series of sprites Im using to animate a UI animation that needs to be on a canvas - theres about 500 because I exported a png sequence from aftereffects and I flip through them with a canvas image with this:
public class VideoPlayerRawImage : MonoBehaviour
{
public Sprite[] frames;
public int framesPerSecond = 60;
public int index;
public bool paused;
Image image;
float t;
public bool pause;
public bool done;
private void Start()
{
image = GetComponent<Image>();
}
void Update()
{
if (!pause)
{
t += Time.deltaTime;
if (frames.Length > 0 && !done)
{
index = (int)(t * framesPerSecond) % frames.Length;
image.sprite = frames[index];
}
}
//repeat
if(index >= frames.Length-1)
{
done = true;
}
}
}
Ive compressed sprites like this:
And ive done this before with textures. Problem is, with these sprites added, I get a black screen after I launch the app, before the scene loads and after unity logo. What can I do to fix this? I need to use sprites because I need it on a canvas.
Unity:
I'm assuming you can not simply use a VideoPlayer component instead and rather load a video than a PNG file for each frame for the same reason I once did: The Alpha Channel.
Anyway importing every frame as PNG file and switching the sprite every frame is very unefficient!
So if it isn't about the alpha chanel anyway just use a VideoPlayer with a video clip and jump to step 3.2. down here using the video file instead of single frames/WebM file.
If the issue is the alpha chanel:
I have found a solution once for having a GIF-like texture but maintaining transparency
requires Adobe MediaEncoder (can be tested free for 30 days).
1. Somewhere get the single images from as PNG
I rendered mine using Blender3D but you can ofcourse use any PNG frames with (or without) transparency.
You seem to have those already anyway. However, the frame files should have a consequent numbered naming like e.g. frame_001.png, frame_002.png, etc.
2. Encode the PNG files to a WebM video format
Install the WebM codec for Adobe Premiere and MediaEncoder
Open the Adobe MediaEncoder
Go to File->AddSource...
Select the first frame of your animation and make sure PNG file sequence is enabled.
In the Queue view click on the current target codec
As format select WebM (only available after installing the plug-in in step 1.)
in the Image Settings section you can either adjust the settings or simply click on Match Source
In the Codec Settings switch to VP8 since Unity doesn't support VP9 (yet?)
You might want to make further adjustments but the most important: Enable Include Alpha Channel
When you think you are done hit Ok at the bottom of the window
Back in the Queue view click on the play symbol to start encoding
after finishing and closing Adobe MediaEncoder you will find the result in the same folder your source frames where in
3. Finally use the WebM "GIF" with transparency in Unity
Import the two result files into your Unity Project.
In the Assets do right-click -> Create -> RenderTexture
Name it and change the size maybe (the rest should be fine.)
Somewhere in you Scene on a manager GameObject have a VideoPlayer component. You need only one (per gif texture). Here use the imported WebM file as VideoClip and the created RenderTexture from step 2. as Target Texture.
Enable Loop and (if you want) Play On Awake (otherwise you'll have to call Play manually.)
Instead of the Image component use the RawImage component and as Texture reference the created RenderTexture from step 2.
Now you have a transparent GIF animation using your original PNG frames within Unity
Just for the file size difference:
The single PNG files (I used 24) for me have about 4.5 mb in total
the WebM file has about 0.5 mb. So this makes it more or less a factor 10 smaller.
Imagine now how much space you might save if you use this instead of 500 PNG files!
Black Screen
while launching the app unity will take some time to load the scene, which is based on the weight of the scene.
Change the background color of the camera to the loading screen video first frame color, by selecting the color from the video using the color picker in the CAMERA--> BACKGROUND. If you do this instead of a black color, video first frame color will occur so it will be seamless and the user won't notice.
we have done the same thing in this game you can check it out : Game link

Emgu.CV load grayscale float32 image as <Bgra, Single>

I am trying to load a small TIFF image using Emgu.CV (2.4.10). The image is a 32bit (float32) single band image, but when loading it using Emgu it opens it as a <Bgra, Single> image.
Is Emgu misinterpreting the image or are there some method to force Emgu to load the image as a <Gray, Single>?
I assume you are trying to read a image from a file. If this is the case you can simply specify the image format and bit depth when declaring the Image.
Image<Gray,Single> myImage = new Image<Gray,Single>("myFile.tiff");

PILLOW enhance module messing up HTML Canvas destination out image

As a part of an experiment I'm trying to process images edited in . I am erasing parts of the image like a brush by drawing on it with
ctx.globalCompositeOperation = "destination-out";
I'm converting this canvas to image with ctx.toDataURL() and saving this in the server with a base64 conversion. So the saved image at this stage looks like this:
The white areas are actually transparent. Now I'm putting this same through the Pillow imageEnhance module:
path = imgName
imObj = Image.open(imgName)
enhObj = ImageEnhance.Contrast(imObj)
enhObj.enhance(factor).show()
Though the contrast adjustment has happened properly this is how the image looks:
Any idea why this is happening and how to tackle this?
Its a problem with the application show() is calling which in this case is some Imagemagick viewer. Once saved to disk the image rendered properly. The problem with lossy transparency however still exists with desaturation through ImageEngance.color() module.

how to display a gif image in windows phone 7?

i am trying to load images from facebook. if a user has set a profile picture, then the picture is a jpg, however, if a user has not set one, then the picture is a stub image in gif format. i know that wp7 does not support displaying gif images (out of the box). is there any way to detect if the final picture is a gif or not?
for example, i make a BitmapImage like this:
BitmapImage img = new BitmapImage(new Uri("https://graph.facebook.com/userid1/picture"))
for this uri, the user does not have a profile picture. so i get taken to a stub gif image at https://fbcdn-profile-a.akamaihd.net/static-ak/rsrc.php/v1/yo/r/UlIqmHJn-SK.gif.
if a user does have an image, then i request it as follows.
BitmapImage img = new BitmapImage(new Uri("https://graph.facebook.com/userid2/picture"))
for the above url i get taken to a url like this: https://fbcdn-profile-a.akamaihd.net/hprofile-ak-snc4/000000_1621037713_00000000_q.jpg
my question is then, once i get the BitmapImage object, img, can i determine if this is a JPG or GIF? can i convert it to a JPG if it is a gif?
i looked at some related questions, but the API discussed loaded the image asynchronously, which is not what i wanted at the moment. furthermore, there was poor documentation.
any help is appreciated.
nevermind, i followed the instructions here: Display GIF in a WP7 application with Silverlight. the user gave an excellent walk through.
what you need to do before you do what this user suggested is to download the source code from codeplex.
then you need to download BitMiracle's JPEG library from http://bitmiracle.com/libjpeg/.
go ahead and go into the /src/ImageTools directory and open up ImageTools.Phone.sln. add the ImageTools.IO.Jpeg.Phone project to the solution.
when you build the solution it will complain about not finding BitMiracle's JPEG dll, go ahead and reference that DLL for the Jpeg project. build again, and it should work.
First download the image(any) using Httprequest or Webclient and then convert to jpg or png from gif(if it is gif) in the following way.
GifDecoder gd = new GifDecoder();
ImageTools.ExtendedImage img = new ImageTools.ExtendedImage();
gd.Decode(img, stream); //stream means image stream
PngEncoder png = new PngEncoder();
png.Encode(img, isoFileStreamdownload); //isoFileStreamdownload means stream, which is used to save image in image file like(image.png))
using ImageTools.dll, ImageTools.IO.Gif.dll,ImageTools.IO.Png.dll (Images Tools)
I think it helps to you

Can jpg images support animation?

jpeg image
How is the above jpg image animated? As far as I know jpg format does not support animation.
No, the JPEG file format has no inherent support for animation.
The image you linked is actually an animated GIF disguised with a jpg file extension. (The browser apparently ignores even the MIME type and looks at the file header bytes in such cases.)
If you view the image in firefox, you can right-click on it and select properties:
You'll see Type: GIF image (animated, 54 frames)
Thus, it is a gif-image that has been renamed to .jpg.
For completeness, I'd like to point our that there's Motion-JPEG - sort of a jpg animation.
MJPEGs, usually produced by webcams, are a stream of JPEG files concatenated together, one after another, sometimes delimited by a HTTP header, and served by webcam-webservers with a MIME-Type of multipart/x-mixed-replace;boundary=, where boundary= defines the delimiter.
A search for animated JPEG related projects on github results in two findings:
In case people care about the size of an animated GIF, they strip it into separate JPG frames and tell the browser to exchange these frames in-place via some JavaScript code. For example. (Pawel's answer)
Then there's actually a proposed Animated JPEG standard, which stems from MJPEG and declares framerate and so forth in each JPG frame. Not probable to arrive in browsers anytime soon.
And lastly, I've seen image-hosters to replace large animated GIFs with a mp4 version of the GIF for presentation, plus some Javascript to serve the actual GIF for downloads/non-supported browsers.
And no, JPEG itself, via JFIF, does not offer a facility to animate a JPG file in itself, just as Noldorin already noted in the chosen answer. :shrug:
It is a GIF image... the extension has been changed by hand. Browser engine is smart enough to determine image format regardless of file extension.
var c = 1;
/* Preloading images */
var image1 = new Image();
image1.src = "a1.jpg";
var image2 = new Image();
image2.src = "a2.jpg";
var image3 = new Image();
image3.src = "a3.jpg";
var image4 = new Image();
image4.src = "a4.jpg";
var image5 = new Image();
image5.src = "a5.jpg";
function disp_img(w)
{
if (c == 6)
{
c = 1;
}
var img_src = "a" + c + ".jpg";
document.ani.src = img_src;
c++;
}
t = setInterval("disp_img(c)", 1000);
No JPEG doesn't support animation. Saving a GIF file with .jpeg extension doesn't male it a JPEG file. It's still a GIF file. Because OS Image viewer doesn't look into file extension it rather looks into the content.
If you open that file as binary (in a text editor) you will see the first line contains
GIF89ad�d�˜|� Which is the magic number for GIF.
Yes,
you can make animation using single jpeg. Google "jpeg css sprites". Of course this will not be native animation support by jpeg format.
A bit of a necro-post but since this question popped first when I tried to get info about pixel motion jpeg, here's some additional info.
Since Pixel2, Google created motion jpeg, which is an ordinary jpeg at the end of which there's an mp4 video.
More on this here:
https://android.jlelse.eu/working-with-motion-photos-da0aa49b50c
JPG does not animate. You either saw a series of JPG images rendered with javascript or you saw a GIF file named as a JPG. A web server and browser might still recognize the correct GIF filetype, even if the wrong extension has been added to the filename.
If you open the image file and if it is a sort of GIF format by using a hex editor, you see the following 4 bytes designating that image type is of GIF.

Resources