Local saved bitmap image displayed weird on physical device - c#

I have a part of my application where I am saving photo from CameraCaptureTask. Photos from here in phone's Media Library are fine. I want to save photos also to IsolatedStorage. This is my method for saving:
private void SavePhoto(Stream image, string filename)
{
using (IsolatedStorageFile storageFolder = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream fileStream = storageFolder.CreateFile(filename))
{
var bitmap = new BitmapImage();
bitmap.SetSource(image);
var wb = new WriteableBitmap(bitmap);
wb.SaveJpeg(fileStream, wb.PixelHeight, wb.PixelWidth, 0, 100);
fileStream.Close();
}
}
}
And this is the part of method displaying photo in another page:
{...
using (IsolatedStorageFile storageFolder = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream fileStream = storageFolder.OpenFile(_url, FileMode.Open, FileAccess.Read))
{
BitmapImage image = new BitmapImage();
image.SetSource(fileStream);
}
this.fullImage.Source = image;
}
}
XAML code:
<ViewportControl x:Name="viewport"
ManipulationStarted="OnManipulationStarted"
ManipulationDelta="OnManipulationDelta"
ManipulationCompleted="OnManipulationCompleted"
ViewportChanged="viewport_ViewportChanged">
<Canvas x:Name="canvas">
<Image x:Name="fullImage" HorizontalAlignment="Center"
RenderTransformOrigin="0,0"
VerticalAlignment="Center"
CacheMode="BitmapCache"
Stretch="UniformToFill" >
<Image.RenderTransform>
<ScaleTransform x:Name="xform"/>
</Image.RenderTransform>
</Image>
</Canvas>
</ViewportControl>
Image is loaded and displayed but it's weird, it's kind of stretched on one side and narrowed on second side. I'm sorry, I can't take a screenshot since WP 8.1 upgrade, I don't know why. In Windows Phone Emulator it's working fine though.

I am facing a similar scenario. The image, which I am capturing using PhotoCaptureDevice, I am trying to display it in a separate page (which also implements the zoom pan feature), the image is being shown cropped. If I remove the CacheMode = "BitmapCache" attribute from Image, then the image is no longer cropped. However it makes the zoom & pan of the image very jittery.
It seems that there is a size limit (2000 x 2000) of image size in the Windows Phone environment. See this.
Do have a look at the PhotoPage.xaml and PhotoPage.xaml.cs files in the FilterExplorerWP project . It might help you.

Related

BitmapImage Stretch mode to Image tag in xaml

I am using in xaml with some fix image source, later on I wanted to use local image and wanted to assign to the xaml. But I am not able to use stretch in new image created .
Is there any way to use the stretch in other way ?
My code in xaml :
<Image Source="/Assets/Images/fix.png" Visibility="Visible" x:Name="ContentImage" Stretch="UniformToFill" />
and in C#
if (File.Exists(imagePath))
{
Image newImage = new Image();
BitmapImage logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = new Uri(imagePath);
logo.EndInit();
newImage.Source = logo;
newImage.Stretch = Stretch.UniformToFill;
ContentImage.Source = newImage.Source;
}
It makes no sense to create another Image element. It is also not necessary to call Begin/EndInit. Use the BitmapImage constructor that takes an Uri argument instead.
This should be sufficient:
if (File.Exists(imagePath))
{
ContentImage.Source = new BitmapImage(new Uri(imagePath));
}

WPF: "edit" image and save

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

Rotating an Image in Windows Phone

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);

Take a snapshot of using the rectangle in WP7

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).

How to zoom in and zoom out Images in WP7?

I have made an application which displays Images .Now I want to implement zoom in and zoom out feature(by using two fingertip's) as in native windows phone photo viewer application.Any idea on how to proceed .
Thanks in Advance.
Perhaps the most expedient approach would be to include the Silverlight for Windows Phone Toolkit. This contains a GestureService that will help with pinch and rotate touch gestures. You could apply it to an image like this:-
<Image Source="someSourceUrl" RenderTransformOrigin="0.5, 0.5" CacheMode="BitmapCache">
<Image.RenderTransform>
<CompositeTransform x:Name="transform" />
</Image.RenderTransform>
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener PinchStarted="OnPinchStarted" PinchDelta="OnPinchDelta" />
</toolkit:GestureService.GestureListener>
</Image>
Then in code-behind:-
private void OnPinchStarted(object sender, PinchStartedGestureEventArgs e)
{
initialAngle = transform.Rotation;
initialScale = transform.ScaleX;
}
private void OnPinchDelta(object sender, PinchGestureEventArgs e)
{
transform.Rotation = initialAngle + e.TotalAngleDelta;
transform.ScaleX = initialScale * e.DistanceRatio;
transform.ScaleY = initialScale * e.DistanceRatio;
}
Check out Laurent Bugnion's multitouch sample - http://multitouch.codeplex.com/
if you want simple image viewer that supports multi-touch, I recommend you to use WebBrowser control to display image.
It supports multi-touch zoom and smooth scrolling as well by default. But you must have to copy file to isolated storage from project folder. Here's how I've done:
<Grid x:Name="LayoutRoot" Background="Transparent">
<phone:WebBrowser
Name="MyWebBrowserControl"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0" />
</Grid>
IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();
// if image file does not exist in isolated storage, copy it to there~!
if (!isf.FileExists(filename))
{
StreamResourceInfo sr = Application.GetResourceStream(new Uri(filename, UriKind.Relative));
using (BinaryReader br = new BinaryReader(sr.Stream))
{
byte[] data = br.ReadBytes((int)sr.Stream.Length);
using (BinaryWriter bw = new BinaryWriter(isf.OpenFile(filename, FileMode.OpenOrCreate)))
{
bw.Write(data);
bw.Close();
}
br.Close();
}
}
Dispatcher.BeginInvoke(() => { MyWebBrowserControl.Navigate(new Uri(filename, UriKind.Relative)); });
※ You must set the Build Action of image file to Content

Categories