I need to save an image at Parse, so I need to convert it to byte[]. Any idea how can I achieve this? I've searched for it but none of the options worked for me. I'm using a shared Xamarin Forms project. Here's an example with text :
byte[] data = System.Text.Encoding.UTF8.GetBytes("Working at Parse is great!");
ParseFile file = new ParseFile("resume.txt", data);
I'm beginner and I really need help !
[EDIT] :
For some reason, Xamarin will not let me use "System.Drawing.Image".
I've searched a lot, and I found this but I can't make it work :
public static byte[] ReadFully(System.IO.Stream input)
{
using (var ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
Thanks in advance .
If you choose images from photo gallery, you can use this codes. This codes also aim to pick up an image from photo library in iOS and save it to database as a byte array.
You said that you already have an image to display as the login form but someone who see this may not know how to get an image from your photo library in iOS so I write all of the code to archive the way to get an image and convert it to byte array.I use Prism library but any framework is ok.
If you want to only know how to convert an image to a byte array in Xamarin.forms you can go to the bottom of the codes below as MainPage class.
First, you make a new folder and name it Services. Under this folder you make an interface like this.
using System;
using System.Threading.Tasks;
using Xamarin.Forms;
using System.IO;
using Foundation;
namespace TestUIImage.Services
{
public interface IPicturePicker
{
Task<NSUrl> GetNSUrlAsync();
}
}
Then you write the content of GetNSUrlAsync method.
You need two methods GetNSUrl and OnImagePickerCancelled so that user select an image or cancel to select.
using System;
using System.IO;
using UIKit;
using Xamarin.Forms;
using System.Threading.Tasks;
using Foundation;
namespace TestUIImage.Services
{
public class PicturePickerImplementation : IPicturePicker
{
public PicturePickerImplementation()
{
}
TaskCompletionSource<NSUrl> urltaskCompletionSource;
UIImagePickerController imagePicker;
public Task<NSUrl> GetNSUrlAsync()
{
// Create and define UIImagePickerController
imagePicker = new UIImagePickerController
{
SourceType = UIImagePickerControllerSourceType.PhotoLibrary,
MediaTypes = UIImagePickerController.AvailableMediaTypes(UIImagePickerControllerSourceType.PhotoLibrary)
};
// Set event handlers
imagePicker.FinishedPickingMedia += GetNSUrl;
imagePicker.Canceled += OnImagePickerCancelled;
// Present UIImagePickerController
UIWindow window = UIApplication.SharedApplication.KeyWindow;
var viewController = window.RootViewController;
viewController.PresentModalViewController(imagePicker, true);
// Return Task object
urltaskCompletionSource = new TaskCompletionSource<NSUrl>();
return urltaskCompletionSource.Task;
}
void GetNSUrl(object sender, UIImagePickerMediaPickedEventArgs args)
{
urltaskCompletionSource.SetResult(args.ImageUrl);
imagePicker.DismissModalViewController(true);
}
void OnImagePickerCancelled(object sender, EventArgs args)
{
taskCompletionSource.SetResult(null);
imagePicker.DismissModalViewController(true);
}
}
}
Next, you register your services using DependencyService because selecting an image from your photo gallery in iOS depends on your platform.
using Prism;
using Prism.Ioc;
using TestUIImage.ViewModels;
using TestUIImage.Views;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Prism.Autofac;
using TestUIImage.Services;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace TestUIImage
{
public partial class App : PrismApplication
{
public App() : this(null) { }
public App(IPlatformInitializer initializer) : base(initializer) { }
protected override async void OnInitialized()
{
InitializeComponent();
DependencyService.Register<PicturePickerImplementation>();
await NavigationService.NavigateAsync("NavigationPage/MainPage");
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<NavigationPage>();
containerRegistry.RegisterForNavigation<MainPage>();
}
}
}
Then, you add this code in Info.plist because of the iOS security.
...
<key>NSPhotoLibraryUsageDescription</key>
<string>Picture Picker uses photo library</string>
</dict>
</plist>
Finally, you can call your services in codebehind. In this time, I used Image controller as TestImage and Button controller as PickPictureButton.
using System;
using System.IO;
using System.Drawing;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Foundation;
using Xamarin.Forms;
using TestUIImage.Services;
namespace TestUIImage.Views
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
async void Handle_Clicked(object sender, System.EventArgs e)
{
PickPictureButton.IsEnabled = false;
NSUrl nSUrl = await DependencyService.Get<IPicturePicker>().GetNSUrlAsync();
TestImage.Source = ImageSource.FromStream(() =>
{
var ms = new MemoryStream();
var imagebytes = File.ReadAllBytes(nSUrl.Path);
ms.Write(imagebytes, 0, imagebytes.Length);
ms.Seek(0, SeekOrigin.Begin);
return ms;
});
PickPictureButton.IsEnabled = true;
}
}
}
Here's some code to convert a BitmapImage to a byte[]:
public byte[] ConvertToBytes(BitmapImage bitmapImage)
{
if (bitmapImage != null)
{
MemoryStream memStream = new MemoryStream();
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
encoder.Save(memStream);
return memStream.GetBuffer();
}
return null;
}
Here's some code to convert a byte[] to a BitmapImage:
private void LoadImage()
{
var image = Services.GetImage(_employeeID);
if (image.Image != null)
{
MemoryStream strmImg = new MemoryStream(image.Image);
BitmapImage myBitmapImage = new BitmapImage();
myBitmapImage.BeginInit();
myBitmapImage.StreamSource = strmImg;
myBitmapImage.DecodePixelWidth = 200;
myBitmapImage.DecodePixelWidth = 250;
myBitmapImage.EndInit();
this.DemographicInformation.Image = myBitmapImage;
}
}
This has worked for me many times.
Related
I'm trying to learn and play a bit with Xamarin :)
I wanted to play a simple sound at the end of a certain time and in part I succeeded, this works on the android and ios emulators but when I try to build the app on my iPhone this crush at the moment of sound reproduction!
the code I wrote I copied from here!
so my code is this:
iAudio.cs :
using System;
namespace StopWatch
{
public interface IAudio
{
void PlayAudioFile(string fileName);
}
}
AudioService.cs in Android :
using System;
using Xamarin.Forms;
using StopWatch.Droid;
using Android.Media;
using Android.Content.Res;
[assembly: Dependency(typeof(AudioService))]
namespace StopWatch.Droid
{
public class AudioService : IAudio
{
public AudioService()
{ }
public void PlayAudioFile(string fileName)
{
var player = new MediaPlayer();
var fd = global::Android.App.Application.Context.Assets.OpenFd(fileName);
player.Prepared += (s, e) =>
{
player.Start();
};
player.SetDataSource(fd.FileDescriptor, fd.StartOffset, fd.Length);
player.Prepare();
}
}
}
AudioService.cs in iOS:
using System; using Xamarin.Forms; using StopWatch; using StopWatch.iOS; using System.IO; using Foundation; using AVFoundation; [assembly: Dependency(typeof(AudioService))] namespace StopWatch.iOS {
public class AudioService : IAudio
{
public AudioService()
{ }
public void PlayAudioFile(string fileName)
{
string sFilePath = NSBundle.MainBundle.PathForResource(Path.GetFileNameWithoutExtension(fileName), Path.GetExtension(fileName));
NSUrl url = NSUrl.FromString(sFilePath);
var _player = AVAudioPlayer.FromUrl(url);
_player.FinishedPlaying += (object sender, AVStatusEventArgs e) =>
{
_player = null;
};
_player.Play();
}
}
}
and this is mi MainPage.xaml.cs :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace StopWatch
{
// Learn more about making custom code visible in the Xamarin.Forms previewer
// by visiting https://aka.ms/xamarinforms-previewer
[DesignTimeVisible(false)]
public partial class MainPage : ContentPage
{
Stopwatch stopwatch;
public MainPage()
{
InitializeComponent();
stopwatch = new Stopwatch();
lblStopWatch.Text = "00:00:00";
lblStopWatchAllert.Text = "";
}
private void btnStartClicked(object sender, EventArgs e)
{
stopwatch.Start();
Device.StartTimer(TimeSpan.FromMilliseconds(10), () =>
{
lblStopWatch.Text = stopwatch.Elapsed.ToString().Substring(0, 8);
controll(lblStopWatch.Text);
return true;
});
}
private void btnStopClicked(object sender, EventArgs e)
{
stopwatch.Stop();
}
private void btnResetClicked(object sender, EventArgs e)
{
stopwatch.Reset();
}
private void controll(String time)
{
if (string.Compare(time, "00:00:03:0000") > 0)
{
stopwatch.Reset();
lblStopWatchAllert.Text = "time is over!";
DependencyService.Get<IAudio>().PlayAudioFile("Alert.mp3");
}
}
}
}
the code crashes me at this point of the iOS AudioService.cs file:
I think the problem lies in the info.plist (although I am most likely wrong) but I don't know how to solve it :(
can someone help me? thank you
I have checked this code , it works in my site . Invoking the play method as follow :
DependencyService.Get<IAudio>().PlayAudioFile("Alan_Walker.mp3");
The other codes are the same with yours in iOS and Android , they all play the sound successfully.
Here you need to notice that ,the local sound file should be added to each platform .And each platform has its specical folder to put the auido file .
In Android , you need to put it in Assets folder as follow :
And in iOS , you need to put it in Resources folder as follow :
==========================Update===================================
You should first add file to this folder as follow :
Then add Existing file to this folder :
Then when installing app , this filw will be added to mobile . No matter what is a simulator or a physical device.
Note :
Not copying file from other path to Xamarin.iOS project , this can't make sure the file be added to the project .
My aim is to save the all form data via button click (as opposed to upon closing). To that end, I've used the example given in the following thread. Saving the form state then opening it back up in the same state
I've tried to adapt my code to the best of my ability, but nothing happens, and there are no errors shown. What am I doing wrong?
Here's the relevant parts of my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
namespace WindowsFormsApplication1
{
public partial class frmPayroll : Form
{
SaveData sd = new SaveData();
public frmPayroll()
{
InitializeComponent();
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
writeConfig();
}
private void writeConfig()
{
using (StreamWriter sw = new StreamWriter("config.xml"))
{
sd.Married = rdoMarr.Checked;
sd.PayPd = cbPayPd.Text;
sd.Allow = cbAllow.Text;
sd.Gross = txtGross.Text;
sd.Fit = txtFit.Text;
sd.Soc = txtSoc.Text;
sd.Med = txtMed.Text;
sd.NetPay = txtNet.Text;
sd.PayPd = cbPayPd.Text;
XmlSerializer ser = new XmlSerializer(typeof(SaveData));
ser.Serialize(sw, sd);
}
}
private void frmPayroll_Load(object sender, EventArgs e)
{
if (File.Exists("config.xml"))
{
loadConfig();
}
sd.Married = rdoMarr.Checked;
sd.PayPd = cbPayPd.Text;
sd.Allow = cbAllow.Text;
sd.Gross = txtGross.Text;
sd.Fit = txtFit.Text;
sd.Soc = txtSoc.Text;
sd.Med = txtMed.Text;
sd.NetPay = txtNet.Text;
}
private void loadConfig()
{
XmlSerializer ser = new XmlSerializer(typeof(SaveData));
using (FileStream fs = File.OpenRead("config.xml"))
{
sd = (SaveData)ser.Deserialize(fs);
}
}
}
public struct SaveData
{
public bool Married;
public string PayPd;
public string Allow;
public string Gross;
public string Fit;
public string Soc;
public string Med;
public string NetPay;
}
}
You are loading your object by deserializing.
But Where are you assigning the states back to your controls?
look at frmPayroll_Load function.
You are trying to assign the data back to the object again.
You have to assign data back to form controls.
Should be something like this (you may need to apply data conversions if required):
rdoMarr.Checked = sd.Married;
.
.
.
.
txtFit.Text = sd.Fit;
.
.
.
.
Good sir,
Am having C# file in Xamarin.Forms called WebPage, i wish to open the eSearch Entry in a new Window(in a new C# file) but it isn't working just showing blank page.
Here is the code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HtmlAgilityPack;
using Xamarin.Forms;
using System.Diagnostics;
namespace WList
{
public class WebPage: ContentPage
{
Entry eSearch;
Button bButton;
public WebPage()
{
eSearch = new Entry{Placeholder = "Search and go"};
bButton = new Button { Text = "GO" };
bButton.Clicked += bButton_Clicked;
this.Content = new StackLayout
{
Children = {
eSearch, bButton
}
};
}
void bButton_Clicked(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(eSearch.Text)) { DisplayAlert("Empty", "Search item is empty", "OK"); }
else
{
Navigation.PushModalAsync(new SitePage());
//Debug.WriteLine(eSearch.Text);
}
}
}
}
You need to pass your text value in the constructor to the new page.
For Example
Public class SitePage : ContentPage
{
public SitePage(string text)
{
var entry = new Entry();
entry.Text = text;
this.Content = entry;
}
}
You would then navigate to it like:
Navigation.PushModalAsync(new SitePage(eSearch.Text));
Can one render text using DirectWrite to a PictureBox in a WinForm app?
I'm using SharpDX and have gone through the DirectWrite samples trying to build the simplest working case I can.
I created a Form and added only a pictureBox to it. Then the following code. The form displays, but nothing visible with the PictureBox.
Any guidance would be much appreciated.
Thanks!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
//using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SharpDX.Direct2D1;
using SharpDX.DXGI;
using SharpDX;
using SharpDX.DirectWrite;
using AlphaMode = SharpDX.Direct2D1.AlphaMode;
using Factory = SharpDX.Direct2D1.Factory;
namespace d2dwTextEdit
{
public partial class Form1 : Form
{
public Factory Factory2D { get; private set; }
public SharpDX.DirectWrite.Factory FactoryDWrite { get; private set; }
public WindowRenderTarget RenderTarget2D { get; private set; }
public SolidColorBrush SceneColorBrush { get; private set; }
public TextFormat TextFormat { get; private set; }
public SharpDX.RectangleF ClientRectangle { get; private set; }
public Form1()
{
InitializeComponent();
Initialize();
Render();
}
protected void Initialize()
{
Factory2D = new SharpDX.Direct2D1.Factory();
FactoryDWrite = new SharpDX.DirectWrite.Factory();
HwndRenderTargetProperties properties = new HwndRenderTargetProperties();
properties.Hwnd = pictureBox1.Handle;
properties.PixelSize = new System.Drawing.Size(pictureBox1.Width, pictureBox1.Height);
properties.PresentOptions = PresentOptions.None;
TextFormat = new TextFormat(FactoryDWrite, "Calibri", 30) { TextAlignment = TextAlignment.Center, ParagraphAlignment = ParagraphAlignment.Center };
RenderTarget2D = new WindowRenderTarget(Factory2D, new RenderTargetProperties(new PixelFormat(Format.Unknown, AlphaMode.Premultiplied)), properties);
RenderTarget2D.AntialiasMode = AntialiasMode.PerPrimitive;
RenderTarget2D.TextAntialiasMode = TextAntialiasMode.Cleartype;
ClientRectangle = new RectangleF(0, 0, pictureBox1.Width, pictureBox1.Height);
SceneColorBrush = new SolidColorBrush(RenderTarget2D, Colors.White);
SceneColorBrush.Color = Colors.Black;
}
private void Render()
{
RenderTarget2D.Clear(Colors.White);
RenderTarget2D.DrawText("Hello Marshall", TextFormat, ClientRectangle, SceneColorBrush);
}
}
}
Hi I sort of followed your question example but I finally managed to work it out as I would like to independently start writing games, all the draw methods have to be within the beginDraw and endDraw methods of the RenderTarget class'. you also need to implement the RenderLoop class this will give you the callback loop delegate. Apologies for the crudeness of my code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using SharpDX.Direct3D;
using SharpDX.Direct2D1;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using SharpDX.DXGI;
using SharpDX;
using SharpDX.Windows;
using System.Globalization;
using SharpDX.DirectWrite;
namespace dx11
{
public partial class Form1 : Form
{
private SharpDX.Direct3D10.Device _mDevice = null;
WindowRenderTarget wndRender = null;
SharpDX.Direct2D1.Factory fact = new SharpDX.Direct2D1.Factory(SharpDX.Direct2D1.FactoryType.SingleThreaded);
SolidColorBrush scenebrush;
RenderTargetProperties rndTargProperties;
HwndRenderTargetProperties hwndProperties;
SharpDX.Windows.RenderForm form = new RenderForm();
RenderLoop.RenderCallback callback;
public Form1()
{
InitializeComponent();
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
form.Width = 600;
form.Height = 600;
test();
callback = new RenderLoop.RenderCallback(Render);
RenderLoop.Run(form, callback);
}
private void test()
{
rndTargProperties = new RenderTargetProperties(new PixelFormat(Format.B8G8R8A8_UNorm, AlphaMode.Premultiplied));
hwndProperties = new HwndRenderTargetProperties();
hwndProperties.Hwnd = form.Handle;
hwndProperties.PixelSize = new SharpDX.DrawingSize(form.ClientSize.Width, form.ClientSize.Height);
hwndProperties.PresentOptions = PresentOptions.None;
wndRender = new WindowRenderTarget(fact, rndTargProperties, hwndProperties);
scenebrush = new SolidColorBrush(wndRender, Colors.Red);
// scenebrush.Color = Colors.Cornsilk;
form.Show();
}
public void Render()
{
wndRender.BeginDraw();
wndRender.Clear(Colors.DarkBlue);
wndRender.DrawRectangle(new SharpDX.RectangleF(10, 10, 50, 50), scenebrush, 2.00F);
wndRender.Flush();
wndRender.EndDraw();
}
}
}
This should create a blue form with a red square in the top left corner.
You don't actually want to render "into the PictureBox" with an HwndRenderTarget. You actually want to render into the Bitmap that the PictureBox has the job of rendering. You can do that by creating a "shared bitmap" (I'm not familiar with SharpDX specifically but the underlying method is ID2D1RenderTarget::CreateSharedBitmap()), rendering into that, and then invalidating the PictureBox after you call EndDraw().
I have made a generic handler .ashx which is placed on root.
In my UserControls folder I have a user control which want to access this ashx class's static method. But I cannot access ashx class or its method. Does it requried any refrence or registration ?
ashx code:
<%# WebHandler Language="C#" Class="GetTileImage" %>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.SessionState;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.IO;
using System.Net;
public class GetTileImage : IHttpHandler, IRequiresSessionState
{
const string c_key = "dzi";
public void ProcessRequest(HttpContext context)
{
//context.Response.Cache.SetMaxAge(TimeSpan.FromMinutes(60));
}
public bool IsReusable
{
get
{
return true;
}
}
public static Bitmap LoadImage(string imageUrl)
{
Dictionary<string, Bitmap> images = (Dictionary<string, Bitmap>)HttpContext.Current.Session[c_key];
if (images == null)
{
images = new Dictionary<string, Bitmap>();
HttpContext.Current.Session[c_key] = images;
}
Bitmap bmp = null;
if (!images.ContainsKey(imageUrl))
{
try
{
string url = imageUrl;
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
url = HttpContext.Current.Server.MapPath(url); WebClient wc = new WebClient(); Stream fs = wc.OpenRead(url); bmp = new Bitmap(fs); fs.Close();
}
catch { return null; }
} images.Add(imageUrl, bmp); if (images.Count > 5)
{
Dictionary<string, Bitmap>.KeyCollection.Enumerator e = images.Keys.GetEnumerator();
e.MoveNext();
string key = e.Current;
images.Remove(key);
}
return bmp;
}
}
User Control where I am accessing this:
Bitmap bmp = GetTileImage.LoadImage("");
Help plz
I don't think you'll be able to call the code from elsewhere unless you add a namespace for the class:
namespace MyNamespace
{
public class GetTileImage : IHttpHandler, IRequiresSessionState
{
// etc. etc.
}
}
MyNamespace should be replaced with whatever namespace you're using for the rest of your code.
In any case I'm a bit puzzled why this code is in an .ashx at all -- as it stands, because ProcessRequest has no code, the handler won't actually do anything.
No you can't access the Generic handler class method in code behind (aspx,ascx etc). You should have to create a static (not necessary) class (file) under App_Code folder and move this method in it.
public class GetTileImage
{
public static Bitmap LoadImage(string imageUrl)
{
..
}
}
I think this could just be because your code is in your ASHX file, if you used a code-behind file it should be fine. e.g.:
GetTileImage.ashx:
<%# WebHandler Language="C#" CodeBehind="GetTileImage.ashx.cs" Class="MyNamespace.GetTileImage" %>
GetTileImage.ashx.cs:
// < using statements here...>
namespace MyNamespace
{
public class GetTileImage: IHttpHandler
{
// < include necessary overrides... >
public static Bitmap LoadImage()
{
// < code here... >
}
}
}
You should then find you can call GetTileImage.LoadImage elsewhere in your code (tested fine here). As pointed out though already, it would be better to move the LoadImage into a utility class that both your handler and your UserControls will use.