If I open an image using this code I get the correct width and height:
Bitmap bitmap = new Bitmap(#"C:\Users\Javier Escribano\Desktop\sample.png");
var imageHeight = bitmap.Height; //1270
var imageWidth = bitmap.Width; //1650
but If I use this code to show an image on WPF control the image is automatically resized. I want to keep the original dimensions:
ImageSource img = (ImageSource)new ImageSourceConverter().ConvertFromString(
#"C:\Users\Javier Escribano\Desktop\sample.png");
this.image.Source = img;
this.image.Width = img.Height; //1057
this.image.Height = img.Width; // 817
This is very likely caused by a mismatch of ppi (pixels per inch) of the png image and the dpi (dots per inch) of WPF. Scott Hanselman has a good post about it here.
Related
I am visualizing some spatial data using a MeshGeometry3D in WPF. I noticed that passing an ImageBrush to the constructor of DiffuseMaterial makes 3D visualization and manipulation fast and efficient (than say using a VisualBrush). My solution is in the following code block where this.dataMeshModel is a GeometryModel3D that includes the mesh. The problem is that I have to give very high resolutions (1000) to the Bitmap image source to make the grid look nice and distinguishable. Choosing this high dpi seems odd and easily raises memory exceptions. Any suggestion? The data model looks like this for 1000 dpi and this for 4000 dpi. THANKS!
private void assignTexture(Geometry gridGeom, double textureDPI, double gridThickness)
{
// rendering the grid on a DrawingVisual
DrawingVisual dv = new DrawingVisual();
using (var dvc = dv.RenderOpen())
{
dvc.DrawRectangle(Brushes.Tomato, null, gridGeom.Bounds);
dvc.DrawGeometry(null, new Pen(Brushes.Black, gridThickness), gridGeom);
}
if (dv.Drawing.CanFreeze)
{
dv.Drawing.Freeze();
}
//rendering the DrawingVisual to an image
Rect bounds = dv.ContentBounds;
RenderTargetBitmap renderedBitmap = new RenderTargetBitmap(
(int)(bounds.Width * this.textureDPI / 96),
(int)(bounds.Height * this.textureDPI / 96),
this.textureDPI,
this.textureDPI,
PixelFormats.Pbgra32);
renderedBitmap.Render(dv);
// adding the rendered image to create an imagebrush
ImageBrush imBrush = new ImageBrush(renderedBitmap);
//creating the material
DiffuseMaterial dataMeshMaterial = new DiffuseMaterial(imBrush);
this.dataMeshModel.Material = this.dataMeshMaterial;
}
I have a canvas with a background image:
var bi = new BitmapImage(new Uri(imgLocFull));
var ib = new ImageBrush(bi) {Stretch = Stretch.UniformToFill};
MyCanvas.Background = ib;
I am overlaying various shapes on the image, and want the position of the shapes relative to the background image to be fixed.
If my application window is resized, the amount of the image that is cropped, horizontally and vertically, changes, and when my shapes are redrawn, they do not appear in the same position on the background image.
How can I determine how much of the image has been cropped (to apply an adjustment factor to the overlaid objects' positions?) Or is there a better way of fixing the location of a shape relative to the background image?
Here is my present drawing code:
var l = new Ellipse();
var scb = new SolidColorBrush();
scb.Color = Color.FromRgb(rCol, gCol, bCol);
l.Fill = scb;
l.StrokeThickness = 0;
l.Width = 3;
l.Height = 3;
Canvas.SetBottom(l, point.Y); // * clipping factor here?
Canvas.SetLeft(l, point.X); // * clipping factor here?
MyCanvas.Children.Add(l);
EDIT: Further Clarification
Here's a concrete example of what I am trying to achieve. My image is an aerial photograph, and I want to mark a particular geographical feature (with, say, an ellipse.)
When the window is resized, the ellipse doesn't stay on the feature, it stays relative to the left and top of the canvas.
I can get it closer to the right place by moving it using a factor (newx = newheight/oldheight * oldx) but this doesn't quite work because of the UniformToFill stretch mode, which sees some of the image clipped off the canvas.
The Top and Left of the Canvas are 'anchored', while the Bottom and Right move when resizing... try setting the Canvas.Top Attached Property instead, along with the Canvas.Left Attached Property as you are:
var l = new Ellipse();
var scb = new SolidColorBrush();
scb.Color = Color.FromRgb(rCol, gCol, bCol);
l.Fill = scb;
l.StrokeThickness = 0;
l.Width = 3;
l.Height = 3;
Canvas.SetTop(l, point.Y); // * clipping factor here?
Canvas.SetLeft(l, point.X); // * clipping factor here?
MyCanvas.Children.Add(l);
UPDATE >>>
You asked Or is there a better way of fixing the location of a shape relative to the background image?
I answered this question, so I don't understand why you would need to do anything else... your objects will not move when the screen in resized *if you only set the Grid.Top and Grid.Left properties.
Does anybody knows how to image cropping in silverlight without any library.
I have Child window and inside the child window I havev a image and this image center one rectange is there so I can panning the image to the around the rectange and selecet the perticular part of the image and this selected part I want to crop.
Also I am using WriteableBitmap and try to Crop, this will not work if correct me if I am wrong.
sheetRectangle.Children is the Image.
foreach (ucPicRect item in sheetRectangle.Children)
{
WriteableBitmap obj = new WriteableBitmap(item.imgCell.Source as BitmapSource);
obj.Crop(0,0,400,400);
obj.Invalidate();
item.imgCell.Effect = dlgcwEditPhoto.imgEdit.Effect;
item.imgCell.Source = obj;// dlgcwEditPhoto.imgEdit.Source;
}
Thanks...!!!
you can use this utility function to crop your image
public static WriteableBitmap cropImage(Image image, double[] coordonnee)
{
Image cloneImage = new Image();
cloneImage.Source = image.Source;
RectangleGeometry myRec = new RectangleGeometry();
myRec.Rect = new Rect(coordonnee[0], coordonnee[1], coordonnee[2], coordonnee[3]);
cloneImage.Clip = myRec;
TranslateTransform t = new TranslateTransform();
t.X = -coordonnee[0];
t.Y = -coordonnee[1];
WriteableBitmap wb = new WriteableBitmap(cloneImage, t);
wb.Invalidate();
return wb;
}
good luck !!
I'm trying to use the microsoft_maps_mapcontrol. I see how one could create a pushpin and the lat long location... but i can't figure out how to instead use an image in place of that pushpin. doesn't look like pushpin will allow using a different image. So, that being the case how do you create an image and then wire it to the proper spot. Once wired can will i be able to use an event for when that image is clicked on.
thanks
shannon
added 3/2/2010
I've looked at the example given at http://www.microsoft.com/maps/isdk/silverlightbeta/#MapControlInteractiveSdk.Tutorials.UIElements.Media.TutorialPositionPointMedia
and i must not be converting something correctly to vb.
Here is there code
Image image = new Image();
image.Source = new BitmapImage(new Uri(ImageUriValue.Text, UriKind.RelativeOrAbsolute));
double opacity;
if (double.TryParse(OpacityText.Text, out opacity))
{
image.Opacity = opacity;
}
image.ImageFailed += MediaFailed;
Point point = GetPoint();
Canvas.SetLeft(image, point.X);
Canvas.SetTop(image, point.Y);
myCanvas.Children.Add(image);
element = image;
and what i converted it to
Dim image As New Image()
image.Source = New BitmapImage(New Uri("\Images\1.png", UriKind.RelativeOrAbsolute))
Canvas.SetLeft(image, 100)
Canvas.SetTop(image, 100)
myCanvas.Children.Add(image)
element = image
Hopefully that helps in spotting what i'm not doing correctly.
thanks
shannon
Here's a code snippet that should show you how to add an image.
public void addImageToMap()
{
MapLayer imageLayer = new MapLayer();
Image image = new Image();
//Define the URI location of the image
image.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("myimage.png", UriKind.Relative));
//Define the image display properties
image.Opacity = 0.8;
image.Stretch = System.Windows.Media.Stretch.None;
//The map location to place the image at
Location location = new Location() { Latitude = -45, Longitude = 122 };
//Center the image around the location specified
PositionOrigin position = PositionOrigin.Center;
//Add the image to the defined map layer
imageLayer.AddChild(image, location, position);
//Add the image layer to the map
TestMap.Children.Add(imageLayer);
}
http://msdn.microsoft.com/en-us/library/ee681895.aspx
Link this post I want to be able to read an image files height and width without reading in the whole file into memory.
In the post Frank Krueger mentions there is a way of doing this with some WPF Imaging classes. Any idea on how to do this??
This should do it:
var bitmapFrame = BitmapFrame.Create(new Uri(#"C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Winter.jpg"), BitmapCreateOptions.DelayCreation, BitmapCacheOption.None);
var width = bitmapFrame.PixelWidth;
var height = bitmapFrame.PixelHeight;
Following Sir Juice's recommendation, here is some alternative code that avoids locking the image file:
using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var bitmapFrame = BitmapFrame.Create(stream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.None);
var width = bitmapFrame.PixelWidth;
var height = bitmapFrame.PixelHeight;
}