Open a picture (jpg.) in F# - f#

I would like to open several pictures (.jpg) with F#.
All my pictures are stored in afile (filepath). I would like to show them to the user.
How can I do this using F#?
To open one picture, it tried something like :
open System.IO
let editPicture filepath =
let fileStream = File.Open(filepath,FileMode.Open)
fileStream.Visible <- True
but it doesn t work.

Here is a minimal quick and dirty WinForms F# snippet that shows a .jpg image on a screen:
open System
open System.Windows.Forms
open System.Drawing
let form = new Form()
let pb = new PictureBox()
pb.Image <- Image.FromFile(path-to-file-with-your-jpg-image)
pb.SizeMode <- PictureBoxSizeMode.AutoSize
form.Controls.Add(pb)
[<STAThread>]
do
Application.Run(form)
This may give you some initial traction and feel on what is involved into reaching your goal. But overall I agree with Carsten König that learning curve for doing UIs with F# is quite steep.

Related

Plotly.Net offline use

Is it possible to run Plotly.Net offline with F#?
You can store "plotly-2.6.3.min.js" and "require.min.js" locally and replace paths to html/javascript and see graphs. But when using Geo Maps, how to handle with world_50m or world_110m.json as needed also to draw a map?
For example first "baseMapOnly" from here https://plotly.net/05_0_geo-vs-mapbox.html and world_110m.json downloaded and pointed to GeoJson:
open Plotly.NET
// world_110m.json stored locally
let geoJsondata =
IO.File.ReadAllText("world_110m.json")
|> JsonConvert.DeserializeObject
let baseMapOnly =
Chart.PointGeo(GeoJson = geoJsondata, locations = [])
|> Chart.withMarginSize(0,0,0,0)
....
baseMapOnly
|> Chart.show
Also "https://cdn.plot.ly" and "https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6" of generated html replaced to local paths of "plotly-2.6.3.min.js" and "require.min.js".
When I try to render a map plot, there is still a call to https://cdn.plot.y/world_110m.json even though paths changed to html file.
What is wrong? Is there some other place to add local path?

Avalonia: How to display PNG as image?

I haven't seen an F# example of accomplishing this, or any examples similar enough to what I am trying to do, so hopefully a solution here will be helpful to others.
I am using Avalonia with F# to build a simple UI. I want to include images in my UI, but have spent hours looking at documentation and examples and everything I've seen looks to be overcomplicated (maybe it really is just that complicated?).
I am creating an image like:
let b = (Avalonia.Media.Imaging.Bitmap #"C:\Images\icon.png")
Image.create [
Image.source b
]
This just displays nothing. What am I missing here?
To add more detail to my comment above, here's what works for me:
let view =
Component(fun ctx ->
let b = new Avalonia.Media.Imaging.Bitmap("Small.png")
Image.create [
Image.source b
]
)
Result is:

How to use Crystal Report in FsXaml

I have added Report.rpt and a Report.fs file by right clicking on project in Solution Explorer. In Report.fs I have declared two Type Report() and CachedReport(), which in C# are generated automatically, and added F# code in it by looking at a .cs file which CrystalReport generated in a C# WPF Projet. In Xaml I have
<ContentControl Content="{Binding ShowReport}"/>
<Button Command="{Binding ViewReport}" Content="Click" Grid.Row="1"/>
and in ViewModel
let doc = new CrystalReportsViewer()
let setSource() =
let rpt = new Report()
rpt.Load("~/Report.rpt")
doc.ViewerCore.ReportSource <- rpt
member x.ShowReport = doc
member x.ViewReport = self.Factory.CommandSync(setSource)
When I start the application I can see CrystalReport Viewer in place. If I click the button Application closes automatically.
If I double click on Report.rpt a dialog box pops up and says This document could not be opened.
How can I use it in F# WPF?
Is there any other reporting tool for F# WPF?
I just need to build a C# Class Library with a Report as embedded resource, add the assembly in F# reference and write ...
let doc = new CrystalReportsViewer()
let setSource() =
let rpt = new MyCsClass.CrystalReport1()
....
doc.ViewerCore.ReportSource <- rpt
thats all!

F# Optional CSV load

I'm using the F# data provider to load csv files. For some reason, not in my control, they occasionally change the file to a gzip. (e.g. MyFile.txt could also be MyFile.text.gz)
So, I have this and it works just fine
let fl = CSV.load("MyFile.txt")
What I need to be able to do is if this errors with file not found, I need it to look for the alternate name.
let fl = CSV.load("MyFile.txt.gz")
I've tried a try...with block
try
let fl = CSV.load("MyFile.txt")
with
let fl = CSV.load("MyFile.txt.gz")
It won't let me use let keyword in this fashion. I even tried
try
let fl = CSV.load("MyFile.txt")
with
CSV.load("MyFile.txt.gz") -> fl
With C#, this would be pretty straight forward. Thanks in advance for any assistance.
You can use something like:
let fl =
try CSV.load("MyFile.txt")
with _ -> CSV.load("MyFile.txt.gz")
But I believe a better solution would be to check if the file exists first.

strip carriage returns from xml serialization in F#

update: some background - i use the xml file to generate a set of pdfs (through a java application that drives JasperReports). all the reports are coming out blank when I use this new xml file. I've ruled out network problems because I use an old xml file from the same server that I run the java application with the new xml file. I've compared the two files (old-good one and new-bad one) using a hex-editor and my first clue is that there are carriage returns in the new file and none in the old one. this may not fix the issue, but I'd like to eliminate it from the equation.
I think I need to remove all the carriage returns from my xml file in order for it to work as I need it to. In my travels, the closest I found is this:
.Replace("\r","")
but where do I use it in the following code? I create my data model, create a root, and pass that to the serializer. At what point can I say "remove carriage returns?"
let def = new reportDefinition("decileRank", "jasper", new template("\\\\server\\location\\filename.jrxml", "jrxml"))
let header = new reportDefinitions([| def |])
let root = reportGenerator(header, new dbConnection(), new reports(reportsArray))
let path = sprintf "C:\\JasperRpt\\parameter_files\\%s\\%d\\%s\\%s\\" report year pmFirm pmName //(System.DateTime.Now.ToString("ddMMyyyy"))
Directory.CreateDirectory(path) |> ignore
let filename = sprintf "%s%s" path month
printfn "%s" filename
use fs = new FileStream(filename, FileMode.Create)
let xmlSerializer = XmlSerializer(typeof<reportGenerator>)
xmlSerializer.Serialize(fs,root)
fs.Close()
XmlWriterSettings has some options for formatting the output, so pass the output through XmlWriter.
You should be able to something like this (don't have FSI at hand right now, don't know if it compiles. :)
//use fs = new FileStream(filename, FileMode.Create)
let settings = new XmlWriterSettings();
settings.Indent <- true;
settings.NewLineChars <- "\n";
use w = XmlWriter.Create(filename, settings);
let xmlSerializer = XmlSerializer(typeof<reportGenerator>)
xmlSerializer.Serialize(w,root)
It's probably not the best solution, but you could try
// after your current code
let xmlString = File.ReadAllText filename
ignore( File.WriteAllText( filename , xmlString.Replace("\r","")))

Resources