I display a photo I took on one of my pages.
I capture the photo in Portrait mode and it works ok.
When I show the picture on my next view, it treats the photo like it was taken in Landscape.
So I need to rotate the picture/image by -90 to correct this.
Here is the relevant code of my .XAML:
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanelx" Grid.Row="1" Margin="0,0,0,0">
</Grid>
And here is the methods where I load the photo and put it into the ContentPanel.:
void loadImage()
{
// The image will be read from isolated storage into the following byte array
byte[] data;
// Read the entire image in one go into a byte array
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
// Open the file - error handling omitted for brevity
// Note: If the image does not exist in isolated storage the following exception will be generated:
// System.IO.IsolatedStorage.IsolatedStorageException was unhandled
// Message=Operation not permitted on IsolatedStorageFileStream
using (IsolatedStorageFileStream isfs = isf.OpenFile("0.jpg", FileMode.Open, FileAccess.Read))
{
// Allocate an array large enough for the entire file
data = new byte[isfs.Length];
// Read the entire file and then close it
isfs.Read(data, 0, data.Length);
isfs.Close();
}
}
// Create memory stream and bitmap
MemoryStream ms = new MemoryStream(data);
BitmapImage bi = new BitmapImage();
// Set bitmap source to memory stream
bi.SetSource(ms);
// Create an image UI element – Note: this could be declared in the XAML instead
Image image = new Image();
// Set size of image to bitmap size for this demonstration
image.Height = bi.PixelHeight;
image.Width = bi.PixelWidth;
// Assign the bitmap image to the image’s source
image.Source = bi;
// Add the image to the grid in order to display the bit map
ContentPanelx.Children.Add(image);
}
}
I am thinking on a simple rotate on the image after I've loaded this. I can do this in iOS, but my C# is skills are worse than bad.
Can anybody advise on this?
If the image is declared in xaml you can rotate it like this:
//XAML
<Image.RenderTransform>
<RotateTransform Angle="90" />
</Image.RenderTransform>
Same thing can be done thru c# also. If you always rotate the image , then doint it in xaml is the better optioin
//C#
((RotateTransform)image.RenderTransform).Angle = angle;
Please try this one:
RotateTransform rt = new RotateTransform();
rt.Angle = 90;
image.RenderTransform = rt;
You can create a RotateTransform object to use for the image's RenderTransform property. This will cause WPF to rotate the Image control when rendered.
If you want to rotate the image about it's center you will also need to set the rotation origin, as shown below:
RotateTransform rt = new RotateTransform();
rt.Angle = 90;
image.RenderTransform = rt;
image.RenderTransformOrigin = new Point(0.5, 0.5);
Related
I'm currently using the below code to put an image on top of another image
Stream stream = client.OpenRead(some URL here);
Bitmap baseimg = (Bitmap)System.Drawing.Image.FromStream(stream);
Bitmap ovlimg = (Bitmap)System.Drawing.Image.FromFile("fanmade.png");
var finalImage = new Bitmap(baseimg.Width, baseimg.Height);
var graphics = Graphics.FromImage(finalImage);
graphics.CompositingMode = CompositingMode.SourceOver;
graphics.DrawImage(baseimg, 0, 0);
graphics.DrawImage(ovlimg, 0, 0);
finalImage.Save("1.png", System.Drawing.Imaging.ImageFormat.Png);
However, the file size turns out to be a lot bigger than expected from 6-9 Mb to 16Mb. So I'm trying to find a more efficient way that would make the file size smaller while still keeping the image quality
Here are both the images
The Base IMG (Changes based on the user input but here's an example): https://pasteboard.co/K6hCXng.png
The overlay IMG: https://pasteboard.co/K6hDvIc.png
I am working on Windows 8 Phone app, I have some images displaying in my app, the images which I have are very big with good quality, now in my app I need to resize the image without disturbing the aspect ratio.
I have searched for it and couldnt find a suitable soultion.
How to achieve this?
Here is my code in .CS file.
string imageName= "path to folder" + name + ".png";
BitmapImage bmp = new BitmapImage(new Uri(imageName, UriKind.Relative));
Image.Source = bmp;
EDIT
More info: Currently i am displaying images in my List Box, so the images are looking very big, so i want to decrease it to lower size without affecting the aspect ratio of the image.
If you want to load reduced image into memory then set DecodePixelWidth without setting
DecodePixelHeight (or other way round)
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.DecodePixelWidth = 80;
bitmapImage.UriSource = new Uri(imageName, UriKind.Relative);
EDIT
Or if you want to keep high resolution image in memory set size for Image control.
<Image ... Width="80"/>
Stretch property is set by default to Uniform which means:
The content is resized to fit in the destination dimensions while it preserves its native aspect ratio.
This should do:
static void Main(string[] args)
{
int _newWidth = 60; //the new width is set, the height will be calculated
var originalImage = Bitmap.FromFile(#"C:\temp\source.png");
float factor = originalImage.Width / (float)_newWidth;
int newHeight = (int)(originalImage.Height / factor);
Bitmap resizedImage = ResizeBitmap(originalImage, _newWidth, newHeight);
resizedImage.Save(#"c:\temp\target.png");
}
private static Bitmap ResizeBitmap(Image b, int nWidth, int nHeight)
{
Bitmap result = new Bitmap(nWidth, nHeight);
using (Graphics g = Graphics.FromImage(result))
g.DrawImage(b, 0, 0, nWidth, nHeight);
return result;
}
If you want to reduce image size proportionally on display, try to play with Image control's Stretch property as demonstrated and explained very well in this blog post.
<Image x:Name="Image" Stretch="UniformToFill"></Image>
The size of an image element is influenced by its containing panel, but this should work in any panel.
<Grid>
<Image Source='flower.png' Width='120' Stretch='Uniform'/>
</Grid>
I am using Bing Maps to make some kind of editor. One of the things the editor needs to do as add an Image to the map and have it not scale. I can add the image with out any problem but I cant seem to keep it from scaling when you change your zoom level. Is there a way to set the scale to be fixed when you create the image and add it to the map. I really want to avoid always changing the scale of the image when the zoom level changes as there can be ton of these images on the map.
I did find this question but that did not seem to fix my problem.
here is the code I am using so far:
MapLayer imageLayer = new MapLayer();
Image image = new Image();
image.Height = 150;
BitmapImage myBitmapImage = new BitmapImage();
myBitmapImage.BeginInit();
myBitmapImage.UriSource = new Uri("../../triangle.jpg", UriKind.Relative);
myBitmapImage.DecodePixelHeight = 150;
myBitmapImage.EndInit();
image.Source = myBitmapImage;
image.Opacity = 0.6;
image.Stretch = System.Windows.Media.Stretch.None;
//The map location to place the image at
Location location = new Location() { Latitude = 37.8197222222222, Longitude = -122.478611111111};
//Center the image around the location specified
PositionOrigin position = PositionOrigin.Center;
imageLayer.AddChild(image, location, position);
MapWithPolygon.Children.Add(imageLayer);
The code you provided won't scale the image when zooming. It's possible that it might look slightly scaled due to the background changing but the physical pixel size of the image will not change. The image will only scale if you bounded it to a LocationRect instead of a location.
I want to do something like that: open an image in the <image> tag and add some other tags on it, for example green rectangle. After that I want to save it like image with rectangle on some part of it. In general user should drag&drop rectangle and could resize it. But the question is: How can I save it? I suppose that I should save parent tag for all of them, for example <grid> or <canvas> but is it possible?
Transform transform = myCanvas.LayoutTransform;
myCanvas.LayoutTransform = null; Size size = new Size(myCanvas.Width,myCanvas.Height); myCanvas.Measure(size);
myCanvas.Arrange(new Rect(size));
RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)size.Width, (int)size.Height, 96d, 96d,PixelFormats.Pbgra32);
renderBitmap.Render(myCanvas);
using (FileStream outStream = new FileStream(path.LocalPath, FileMode.Create))
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
encoder.Save(outStream);
}
myCanvas.LayoutTransform = transform;
For a detailed explanation (and the source of the above code), see this blog post:
http://denisvuyka.wordpress.com/2007/12/03/wpf-diagramming-saving-you-canvas-to-image-xps-document-or-raw-xaml/
You can save as PNG, JPG, etc depending on the encoder that you use
Im working on a WP7-app where I would like to record video and before the video is saved take a snapshot of the video so that it could be used as a thumbnail picture. The thumbnail picture is temporary save in the isolated storage before it is used. For the camera I use a rectangle to record video and later I want to display the picture on the phone.
The problem is that the picture is displays only a black screen. Even when i tried to save the picture in the media library the picture is also there displayed as black. What can be the cause of this problem and how do i solve it?
I inserted the code below:
Here is the rectangle where you capture the video with.
<Rectangle
x:Name="viewfinderRectangle"
Width="640"
Height="480"
HorizontalAlignment="Left"
Canvas.Left="80"/>
Here is the code for taking the picture:
try
{
String tempJPEG = FOSConstants.TEMP_VIDEO_THUMBNAIL_NAME;
var myStore = IsolatedStorageFile.GetUserStoreForApplication();
if (myStore.FileExists(tempJPEG))
{
myStore.DeleteFile(tempJPEG);
}
IsolatedStorageFileStream myFileStream = myStore.CreateFile(tempJPEG);
WriteableBitmap wb = new WriteableBitmap(viewfinderRectangle, null);
wb.SaveJpeg(myFileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
myFileStream.Close();
myFileStream.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error saving snapshot", MessageBoxButton.OK);
}
Here is the code for reading the thumbnail picture from the isolated storage:
private BitmapImage GetIsolatedStorageFile(string isolatedStorageFileName)
{
var bimg = new BitmapImage();
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var stream = store.OpenFile(isolatedStorageFileName, FileMode.Open, FileAccess.Read))
{
bimg.SetSource(stream);
}
}
return bimg;
}
Here is the image where I want to display my thumbnail in the GUI.
<Image Width="180"
Height="180"
Stretch="Fill"
Margin="24,0,0,0"
Source="{Binding Path=ImageSoruce, Mode=TwoWay}"
HorizontalAlignment="Left"/>
Edit: removed misleading stuff about Invalidate() you dont need to do that.
So you can use the GetPreviewBufferArgb32() method to get what the camera is providing at the moment. This can be copied to your writable bitmap as show below.
using (var myStore = IsolatedStorageFile.GetUserStoreForApplication())
{
if (myStore.FileExists(tempJPEG))
{
myStore.DeleteFile(tempJPEG);
}
IsolatedStorageFileStream file = myStore.CreateFile(tempJPEG);
int[] buf = new int[(int)c.PreviewResolution.Width * (int)c.PreviewResolution.Height];
c.GetPreviewBufferArgb32(buf);
WriteableBitmap wb = new WriteableBitmap((int)c.PreviewResolution.Width, (int)c.PreviewResolution.Height);
Array.Copy(buf, wb.Pixels, buf.Length);
wb.SaveJpeg(file, (int)c.PreviewResolution.Width, (int)c.PreviewResolution.Height, 0, 100);
}
The reason your sample code does not work is that the viewfinder brush is set up on the GPU (I think I can remember why I think it is done there, but I think it is). This means that silverlight does not have access too the raw video and when you render the silverlight element, it is blank (as though it has no background).