I'm using WriteableBitmap.Render to convert an InkPresenter control to a byte array and Image.
This is my code:
var bitmap = new WriteableBitmap(element, null);
bitmap.Render(element, null);
bitmap.Invalidate();
BitmapImage img;
using (var ms = new MemoryStream())
{
bitmap.SaveJpeg(ms, bitmap.PixelWidth, bitmap.PixelHeight, 0, 85);
// byte[] bytes = ms.ToArray();
img = new BitmapImage();
img.SetSource(ms);
}
If I save the result (byte array or Image) into IsoladtedStorage, the Image has the correct size but is only black.
I don't have an idea why it does not work because I've already used this method with the Map control.
using (var stream = new MemoryStream())
{
WriteableBitmap dd = new WriteableBitmap(ink, null);
dd.SaveJpeg(stream, dd.PixelWidth, dd.PixelHeight, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
var ml = new MediaLibrary();
ink.Background = new SolidColorBrush(Colors.White);
ml.SavePicture(string.Format("Images\\{0}.jpg", Guid.NewGuid()), stream);
ink.Background = new SolidColorBrush(Colors.Transparent);
}
Related
I'm using geoTools 14.1
I'm trying to plot on an image some points
This is the code I'm using:
double[][] points = new double[8][2];
points[0] = new double[]{45.46433710338643, 9.190417528152478};
points[1] = new double[]{45.46195085146914, 9.189746320685355};
points[2] = new double[]{45.460062304163635, 9.19015527826191};
points[3] = new double[]{45.472950871127445, 9.17363731952788};
points[4] = new double[]{45.4737153001908,9.203728795018847};
points[5] = new double[]{45.4849795331724,9.20162835217198};
points[6] = new double[]{45.48560542313713,9.195953607559215};
points[7] = new double[]{45.48348421787171,9.188765287399292};
final SimpleFeatureType TYPE = DataUtilities.createType("Location",
"location:Point:srid=3857,"+// <- the geometry attribute: Point type
"nome:String," + // <- a String attribute
"id:Integer" // a number attribute
);
FeatureCollection<SimpleFeatureType, SimpleFeature> collection = new DefaultFeatureCollection();
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
CoordinateReferenceSystem pointSrc = CRS.decode("EPSG:4326");
CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:3857");
MathTransform transform = CRS.findMathTransform(pointSrc, targetCRS);
for (int i = 0; i < points.length; i++)
{
double[] coords = points[i];
Point point = geometryFactory.createPoint(new Coordinate(coords[0], coords[1]));
Point converted = (Point) JTS.transform( point, transform);
featureBuilder.add(converted);
featureBuilder.add("Punto "+i);
featureBuilder.add(i);
SimpleFeature feature = featureBuilder.buildFeature(""+i);
logger.info(""+feature+" feature.getDefaultGeometry() "+feature.getDefaultGeometry()+ " feature.getDefaultGeometryProperty() "+feature.getDefaultGeometryProperty());
((DefaultFeatureCollection)collection).add(feature);
}
String wellKnownName = "Circle";
Style style = SLD.createPointStyle(wellKnownName,Color.RED,Color.RED,0f,10f);
FeatureLayer fl = new FeatureLayer(collection, style);
fl.setVisible(true);
fl.setSelected(true);
logger.info(""+fl);
mapcontent.addLayer((org.geotools.map.Layer)fl); //"1010177.1917802,5688070.7096562,1029133.5747922,5704122.4855938"
ReferencedEnvelope bounds = new ReferencedEnvelope(1010177.1917802,1029133.5747922,5688070.7096562, 5704122.4855938, targetCRS);
BufferedImage ret = buildImage(mapcontent, 5000, 5000, bounds, Color.white);
ImageIO.write((RenderedImage) ret, "png", new File("/home/angelo/Scrivania/immagineResult.png"));
It seems to me all correct, but the generated image contains no point.
This is the generated image
As you can see it's all white; I was expecting only 8 red circles on the image... Is there any error in my code? Am I doing anything wrong?
Thank you
Angelo
UPDATE: added build image method
public BufferedImage buildImage(final MapContent map, final int imageWidth,final int imageHeight,ReferencedEnvelope bounds,Color bgcolor) {
GTRenderer renderer = new StreamingRenderer();
renderer.setMapContent(map);
renderer.setMapContent(map);
Rectangle imageBounds = null;
ReferencedEnvelope mapBounds = bounds;
try {
if(bounds==null) mapBounds = map.getMaxBounds();
imageBounds = new Rectangle(imageWidth, imageHeight);
} catch (Exception e) {
failed to access map layers
throw new RuntimeException(e);
}
BufferedImage image = new BufferedImage(imageBounds.width, imageBounds.height, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D gr = image.createGraphics();
int type = AlphaComposite.SRC;
gr.setComposite(AlphaComposite.getInstance(type));
Color c = new Color(bgcolor.getRed(), bgcolor.getGreen(), bgcolor.getBlue(), 0);
gr.setBackground(bgcolor);
gr.setColor(c);
gr.fillRect(0, 0, image.getWidth(), image.getHeight());
type = AlphaComposite.SRC_OVER;
gr.setComposite(AlphaComposite.getInstance(type));
try {
renderer.paint(gr, imageBounds, bounds);
} catch (Exception e) {
throw new RuntimeException(e);
}
return image;
}
After a lot of playing I have found the problem :-) There is no bug in your code! There are in fact 8 red dots in that white image, but they are very hard to find!
As the above image shows at 2000% zoom (and panning along the top edge) you will find a dot (I'm assuming the others are there) - the simple answer is either to make the dots 10 times bigger (100px) or the image much smaller (500x500) and in both cases the dots are immediately visible.
I'm having 10 image urls. I want to download those images and htmls to local folder and replace the image paths in corresponding image source of htmls. How to download 10 images from urls. below code for single image download.
var webClient = new WebClient();
webClient.OpenReadCompleted += WebClientOpenReadCompleted;
webClient.OpenReadAsync(new Uri(webimages["image url"], UriKind.Absolute));
void WebClientOpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
const string tempJpeg = "TempJPEG";
var streamResourceInfo = new StreamResourceInfo(e.Result, null);
var userStoreForApplication = IsolatedStorageFile.GetUserStoreForApplication();
if (userStoreForApplication.FileExists(tempJpeg))
{
// userStoreForApplication.DeleteFile(tempJpeg);
MessageBox.Show("Image Already Exists");
}
var isolatedStorageFileStream = userStoreForApplication.CreateFile(tempJpeg);
var bitmapImage = new BitmapImage { CreateOptions = BitmapCreateOptions.None };
bitmapImage.SetSource(streamResourceInfo.Stream);
var writeableBitmap = new WriteableBitmap(bitmapImage);
writeableBitmap.SaveJpeg(isolatedStorageFileStream, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight, 0, 85);
isolatedStorageFileStream.Close();
isolatedStorageFileStream = userStoreForApplication.OpenFile(tempJpeg, FileMode.Open, FileAccess.Read);
// Save the image to the camera roll or saved pictures album.
var mediaLibrary = new MediaLibrary();
// Save the image to the saved pictures album.
mediaLibrary.SavePicture(string.Format("SavedPicture{0}.jpg", DateTime.Now), isolatedStorageFileStream);
isolatedStorageFileStream.Close();
}
I need to do the following:
Convert base64 image string into Bitmapimage
from BitmapImage in (1), convert it to byteArray
The problem:
how to solve the step(2)
Your help is greatly appreciated. Thanks
public async Task Base64StringToBitmap(string Base64source,string Filenm)
{
var bytes = Convert.FromBase64String(Base64source);
var ims = new InMemoryRandomAccessStream();
var dataWriter = new DataWriter(ims);
dataWriter.WriteBytes(bytes);
await dataWriter.StoreAsync();
ims.Seek(0);
//----- Create Bitmapimage ---------------
var bm = new BitmapImage();
bm.CreateOptions = BitmapCreateOptions.None;
bm.SetSource(ims);
// Update : added this
byte[] pixelBuffer = null;
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap wb = new WriteableBitmap(200, 300);
wb.SetSource(ims);
//-- Problem here :
Stream stm = wb.PixelBuffer.AsStream();
int len = (int)stm.Length;
byte[] pixels = new byte[len];
await stm.ReadAsync(pixels, 0, pixels.Length);
stm.CopyTo(ms);
pixelBuffer = ms.ToArray();
}
}
Check this method
public static byte[] ConvertToBytes(BitmapImage bitmapImage)
{
byte[] data = null;
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap btmMap = new WriteableBitmap
(bitmapImage.PixelWidth, bitmapImage.PixelHeight);
// write an image into the stream
Extensions.SaveJpeg(btmMap, ms,
bitmapImage.PixelWidth, bitmapImage.PixelHeight, 0, 100);
ms .Seek(0, SeekOrigin.Begin);
data = stream.GetBuffer();
}
return data;
}
I want to update my live tile by creating and saving a writable bitmap image in scheduled task agent.my code works inside the app but in background task, it breaks into the debugger
I'm using this simple code:
protected override void OnInvoke(ScheduledTask task)
{
#if DEBUG_AGENT
ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(30));
#endif
CreateWideTile();
NotifyComplete();
}
and my code to create and save image is this:
private void CreateWideTile()
{
int width = 691;
int height = 336;
string imagename = "WideBackground";
WriteableBitmap b = new WriteableBitmap(width, height);
var canvas = new Grid();
canvas.Width = b.PixelWidth;
canvas.Height = b.PixelHeight;
var background = new Canvas();
background.Height = b.PixelHeight;
background.Width = b.PixelWidth;
//Created background color as Accent color
SolidColorBrush backColor = new SolidColorBrush(Colors.Red);
background.Background = backColor;
var textBlock = new TextBlock();
textBlock.Text = "Example text";
textBlock.FontWeight = FontWeights.Normal;
textBlock.TextAlignment = TextAlignment.Left;
textBlock.Margin = new Thickness(20, 20, 0, 0);
textBlock.TextWrapping = TextWrapping.Wrap;
textBlock.Foreground = new SolidColorBrush(Colors.White); //color of the text on the Tile
textBlock.FontSize = 30;
canvas.Children.Add(textBlock);
b.Render(background, null);
b.Render(canvas, null);
b.Invalidate(); //Draw bitmap
//Save bitmap as jpeg file in Isolated Storage
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream imageStream = new IsolatedStorageFileStream("/Shared/ShellContent/" + imagename + ".jpg", System.IO.FileMode.Create, isf))
{
b.SaveJpeg(imageStream, b.PixelWidth, b.PixelHeight, 0, 100);
}
}
}
when I test the app, after executing background task, an error comes that point to Debugger.Break();
private static void UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
Debugger.Break();
}
}
I don't understand the reason. my code works in foreground app but not in background ...
any solution ????
You should use dispatcher, because WriteableBitmap.Render should be used in the UI thread:
protected override void OnInvoke(ScheduledTask task)
{
Deployment.Current.Dispatcher.BeginInvoke( () =>
{
CreateWideTile();
NotifyComplete();
} );
}
I am trying to save a Sprite object as a file on the device I'm working on and it seems to work. the problem I'm having is reading the saved file back and placing it back on stage as a sprite. Below is the code I have so far, could someone tell me what it is I'm doing wrong? I have a suspicion that the saved isn't what I expect it to be since the file sizes have been under a kilobyte.
public function save_album(e:Event):void
{
var outFile:File = File.documentsDirectory; // dest folder is desktop
outFile = outFile.resolvePath("canvas3.bin");
var fs:FileStream = new FileStream();
var bytes:ByteArray = new ByteArray();
//trace (File.documentsDirectory.url + "/canvas2.bin");
fs.open(outFile, FileMode.WRITE);
bytes.writeObject(graffitiContainer) //graffitiContainer is a Sprite
bytes.position = 0;
fs.writeBytes(bytes, 0, bytes.length);
fs.close();
}
public function open_album(e:Event):void
{
var inBytes:ByteArray = new ByteArray();
var inFile:File = File.documentsDirectory;
inFile = inFile.resolvePath("canvas3.bin"); // name of file to read
var inStream:FileStream = new FileStream();
inStream.open(inFile, FileMode.READ);
inStream.readBytes(inBytes, 0, inBytes.length);
inStream.close();
inBytes.position = 0;
ui.removeChild(graffitiContainer);
var obj:Sprite = inBytes.readObject() as Sprite; //returns a null
graffitiContainer = obj;
ui = new UIComponent();
graffitiContainer.x = 0;
graffitiContainer.y = 100;
ui.addChild(graffitiContainer);
}
Not fully sure I understand what you're trying to accomplish; however, this implementation doesn't do what you're thinking - writeObject could only serialize general public properties, and not the graphics member.
You could render it to a Bitmap.
Saw a blog post about this:
http://jacwright.com/201/serializing-display-objects/