Edit: my issue was that in using SkiaSharp to scale down the image size I was encoding it as Jpeg instead of PNG. Encoding as PNG made the background transparent.
I am loading images from an HTTP endpoint, storing the image in a DB, and displaying the image in an ImageSource. I have a PNG with a transparent background. When the image is displayed the background turns black. I'm not sure where I'm going wrong.
Is what I'm doing even possible? Download a PNG from HTTP with a transparent background, save PNG as byte[] in a database, and displaying the image in a ContentPage with the transparent background?
Should I abandon DB storage for this image and save it on the filesytem?
Download Image as ByteArray and Convert to ImageSource
public ImageSource Image { get; set;} // NotifyPropertyChange is implemented
...
// download image
var client = new HttpClient();
var imageByteArray = await client.GetByteArrayAsync(url);
// convert ByteArray to ImageSource
Image = ImageSource.FromStream(() => new MemoryStream(imageByteArray));
XAML ImageSource
<Image x:Name="image"
Source="{Binding Image}" />
Sqlite DB Model Property & Conversion from ByteArray to ImageSource
public byte[] ImageByteArray { get; set; }
...
// convert ByteArray to ImageSource in Model
Image = ImageSource.FromStream(() => new MemoryStream(ImageByteArray));
Question-asker states in a comment that the actual problem was that they used SkiaSharp to scale the image to a smaller size. At that step, they encoded the resulting image in JPEG - so it no longer had transparency.
"Changing the encode to PNG fixed my issue."
As an aside, if transparency isn't there, its important to examine the process in every step from image creation to storing on server to transmitting to client to final display. Examine output of each step, to be sure it is still .png format, and has transparency. (E.g. take the bytes, store them in a file, manually view that file in an image viewer that shows transparent areas.)
Related
I have a page that displays data about an object. At the top of the page is room for an icon, showing a picture of that object. Tapping this icon brings up a new page that allows the user to take a new picture, and save it as a temporary new picture for the object (not put in database, but should persist for the session)
Initial page:
private var source:Object = new Object();
protected function onInitialize():void {
source = navigator.poppedViewReturnedObject;
}
When setting source for the image later...
if (source != null) {
pic.source = source.object;
}
else {
pic.source = "no_picture_available_image.png";
}
2nd Page (User can take picture, and view new picture):
[Bindable]
private var imageSource:Object = null;
<s:Image id="pic" width="90%" height="75%" horizontalCenter="0" source="{imageSource}" />
After taking picture...
protected function mediaPromiseLoaded(evt:Event):void {
var loaderInfo:LoaderInfo = evt.target as LoaderInfo;
imageSource = loaderInfo.loader;
}
This does show the picture just taken correctly on this page.
To get back to old page, i use navigator.popView, and use:
override public function createReturnObject():Object {
return imageSource;
}
Unfortunately, it doesn't work. The imageSource isn't null when it is read from navigator.poppedViewReturnedObject, but no image is shown.
Does the LoaderInfo not persist after popping the view? Are the camera pics not automatically saved? I can't find answers to any of these questions, and I can't debug using the phone in my current environment.
After thinking about this a bit, don't return LoaderInfo.loader as the poppedViewReturnedObject. If I remember correctly, a DisplayObject can only be set as the source of one Image. Instead, return LoaderInfo.loader.content.bitmapData. That BitmapData should be the raw data used to display the image. This data can be used repeatedly to create images and can be set as the source of an Image.
Problem turned out to be in my first page's image declaration - I didn't set a width. Seemingly, the object being displayed couldn't handle not having a specified width.
Note that passing back the loader did work fine.
i want to add dynamically images in asp.net using C#. after this i want to change image as selected on client side click event. i do not know for this what i will use. please anybody solve my problem. for problem reference: huitsuit dashboard lending page.
Create new Page which should create image runtime as follows:
string s = Server.MapPath("original.jpg");
string s2 = Server.MapPath("ikon.gif");
System.Drawing.Image original= Bitmap.FromFile(s);
Graphics gra = Graphics.FromImage(original);
Bitmap logo = new Bitmap(s2);
gra.DrawImage(logo, new Point(70, 70));
Response.ContentType = "image/JPEG";
big.Save(Response.OutputStream, ImageFormat.Jpeg);
Now in your existing page Implement ICallBack interface
( http://msdn.microsoft.com/en-us/library/ms178208.aspx )
in response of ICallback interface you can set image source to you image aspx page.
e.g
<image src='Image.aspx'>
Here's what I want to do. An image is loaded by default when the app is run. There is a way to load another image the user wants by specifying an url. When the user defined image is loaded, the default image is still in the background and there are some method that would be used to apply some filters on the image as a whole (I mean the resultant image with both the default and the user loaded image blended) and then I want to save the final image as jpg or png.
Now, I am still a beginner at Flex, and getting all confused with all the canvas, image control, bitmapdata etc. Where I want help is what's the best way to implement what I want? Should I load the default image into an Image with url/embed or should I load it as a BitmapData, how do I load the second user defined image? Whats the best way to blend the two images?
You can leave the default image as embedded one, and retrieve its BitmapData to work with further.
When the user-defined image is loaded, you retrieve its BitmapData, and draw the embedded image over the user-defined one:
/**
* An embedded image's class (your default image)
*/
[Embed(source="/assets/logo.png")]
public static var Logo:Class;
/**
* #param bitmapData: The user-defined BitmapData that you want to modify
* #param matrix: The transofrmation matrix applied to the resulting BitmapData
*/
public function getCustomBitmapData(bitmapData:BitmapData, matrix:Matrix):BitmapData
{
// Initialize and drawing the resulting BitmapData's first layer
var result:BitmapData = new BitmapData(bitmapData.height, bitmapData.width);
result.draw(bitmapData, matrix);
// Load the BitmapData of the embedded Logo image
var bitmapAsset:BitmapAsset = new Logo();
var logoBd:BitmapData = bitmapAsset.bitmapData;
// Draw the logo over the result with an alpha of 0.3
result.draw(logoBd, matrix, new ColorTransform(1, 1, 1, .3));
//TODO: You should play with the size of the images, apply filters, etc.
return result;
}
Then you can save the resulting BitmapData instace to the local file system:
/**
* Save the BitmapData to a local file
* #param bitmapData: the data to save
*/
public function saveBitmapData(bitmapData:BitmapData):void
{
// Initialize the encoder
var pngEncoder:PNGEncoder = new PNGEncoder();
// Encode the BitmapData and save its byte array
var imageBytes:ByteArray = pngEncoder.encode(bitmapData);
// Create a new FileReference:
var imageFile:FileReference = new FileReference();
// Save the file:
imageFile.save(imageBytes, "myimage.png");
}
How can I copy or duplicate the bitmapdata from a mx:image component?
I need to display the same image in multiple screens of my application and don't want to have to download the image multiple times.
I could just use a urlrequest to download the image as a bitmap and copy that but I like the way you can can just set the source of the image component.
Image extends SWFLoader which has a content property that will contain the Bitmap object that was loaded. Wait for the image to load, cast the content to Bitmap and read its bitmapData
public function imageLoadCompleteHandler(e:Event):void
{
var bitmap:Bitmap = img.content as Bitmap;
if(bitmap == null) {
trace("loaded content is not an image");
return;
}
bmpData = bitmap.bitmapData;
//hurray..!
}
Actually after reading the message above (and trying stuff out) I think this is wrong. The Complete listener fires on my second image so I guess it is loading it twice. Oh well.
I couldn't place the whole Flex doc, but this seemed to work. I added this to the Application tag: applicationComplete="Run();"
The following is wrapped in a mx:Script tag:
import mx.controls.Image;
private function Run():void
{
var i:Image = new Image();
i.source = first.source;
addChild(i);
}
And this is just a Image outside of the script tag:
<mx:Image x="12" y="125" source="e53c04a51d5992fb77ab1e20c45ddc9f.jpeg" id="first" />
I also tried this after setting the i source:
first.source = null;
Just to see what happens, the i image keeps it's source
I am writing a Flex application to receive xml from an httpservice. That works because I can populate a datagrid with the information. The xml sends image pathnames. A combobox sends a new HttpService call onChange. This repopulates the datagrid and puts new images in the folder that flex is accessing.
I want to dynamically change the image without changing the pathname of the image.
<mx:Canvas id="borderCanvas"><mx:Canvas id="dropCanvas">
<mx:Tile id="adTile"><mx:Image></mx:Image>
</mx:Tile></mx:Canvas></mx:Canvas>
This is my component.
I assign my Image sources using this code:
var i:Number = 0;
while ( i <= dg_conads.rowCount){
var img:Image = new Image();
img.source = null;
img.source = imageSource+i+".jpg";
adTile.addChild(img);
i++; }
My biggest problem is that the images are not refreshing. I get the same image even though I've prevented caching from the HTML wrapper and the ASP.Net website. The image automatically loads in the folder and refreshes in the folder but I can't get the image to refresh in the application.
I've tried removeAllChildren(); delete(adTile.getChildAt(0)); and neither worked.
I would try using:
img.load(imageSource + i + ".jpg");
If that doesn't work, try appending a random number on the end ie:
img.source = imageSource + i + ".jpg?" + Math.random();
Have you tried to add id="img" into the mx:Image tag directly and remove adTile.addChild(img);
in the script?