Load Bitmap into memory in Unity using System.Drawing - c#

Using Unity 2017.4.33f1-Personal.
I'm trying to use the Image.FromFile method in the System.Drawing namespace to load a Bitmap in a GameObject's logic. Please note that I am not interested in saving this bmp as an asset or anything like that. I am only looking to load it into RAM where I can do some calculations. I have tried the following:
var result = Image.FromFile(
AssetDatabase.GetAssetPath(mainImg)
) as Bitmap;
But I get the following error:
InvalidProgramException: Invalid IL code in System.Drawing.Image:FromFile (string): IL_0000: ret
FYI,
mainImg is a reference to a Texture2D resource
AssetDatabase.GetAssetPath(mainImg) resolves to Assets/CustomPackages/SeededConstruction/PuzzleBuilder/Input/main.bmp
I've also tried a bunch of other goofy things, including getting the absolute path and replacing forward slashes with backslashes like this:
var result = Image.FromFile(
Directory.GetCurrentDirectory()
+ "\\"
+ AssetDatabase.GetAssetPath(mainTileset)
.Replace('/', '\\')
) as Bitmap;
In this case, the path resolves to D:\_Projects\2dGenerator\PlatformGeneration\Assets\CustomPackages\SeededConstruction\PuzzleBuilder\Input\main.bmp. However, this returns the same error as above.
What am I doing wrong here? It seems like this methodology works fine in normal .Net applications, why not in Unity?

It turns out it was not any kind of filepath issue. In order to properly reference System.Drawing in Unity 2017.4.33f1-Personal, I took the following steps:
Go to Edit -> Project Settings -> Player. Change the API Compatability Level from .NET 2.0 Subset to .NET 2.0.
Add an mcs.rsp to my unity projects root Asset folder. Open in it in a text editor and on the first line, enter: -r:System.Drawing.dll. Save.
Close and reopen Unity.

Related

C# Reporting Error in Processing 'Illegal Path'

I am trying to get reporting in C# to work. I'm trying to embed my rdlc file as such:
var reportDataSource = new ReportDataSource("ProspectsDataSet", _allProspects);
ReportViewer.LocalReport.DataSources.Add(reportDataSource);
ReportViewer.LocalReport.ReportEmbeddedResource = "SdcDatabase.Modules.EnquiryModule.View.Reports.ProspectsReport.rdlc";
ReportViewer.ZoomMode = ZoomMode.PageWidth;
ReportViewer.RefreshReport();
The build action on the rdlc file itself is set to embedded resource and the copy to output directory set to copy always.
I have double checked and I'm certain that that is the correct namespace in the ReportEmbeddedResource string. However when I try to load the report I get this error:
I have tried switching a few things around in the path, such as replacing '.' with '/' and '\' but so far I have not been able to get anything to fix this. I have also tried using LocalPath instead of EmbeddedResource but again I come across errors.
I have searched for this issue but haven't found anything to resolve my issue thus far.
I have a reporting wrapper class that works well for my apps. I have a property to hold the name of the ".rdlc" report definition I want to run. Then, when I call my "RunReport()" method, I assign the report based on reading a stream from my application assembly resource. A short version for what you have might be
ReportViewer.LocalReport.LoadReportDefinition( GetRDLCStream( "ProspectsReport.rdlc" ));
Then, lower, I have a method
private Stream GetRDLCStream( string rptRDLC)
{
var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(
"SdcDatabase.Modules.EnquiryModule.View.Reports." + rptRDLC);
return stream;
}
Obviously, I am not positive of the naming convention of your path to your project but am implying the above path. However, it should reflect (for example)
"NameOfYourApp.SubFolderWithinPath.MaybeReportsSubFolder." + actualReport.RDLC name
This way, I never have to worry about copying out a resource and hoping the paths work. I know it is embedded and where within the assembly.

Unity3D: Finding folder path when Building the project

I am extracting some information from several text files in different folders. For that purpose I created an application with several Input Fields to write the folders' name that I want to go. Everything went well in Editor Mode.
However when I build the project and run the ".exe" file created, it can't find the text files I want. I show below the code I am using to extract the files. The first data.path is the one I used on my Editor and worked well while the second (commented) data.path is one trial that I tried by placing my folder on the ".exe" Data folder. But it didn't work...
data.motion = input_text;
data.subjectName = input_text2;
data.path = "C:/Users/Matias/Desktop/Acquisition_Data/Kinect1/" + data.subjectName + "/" + data.motion + ".txt";
/*data.path = Application.dataPath + "/Acquisition_Data/Kinect1/" + data.subjectName + "/" + data.motion + ".txt";*/
data.lines = System.IO.File.ReadAllLines(data.path);
I can't get any explanation why any of these methods work when I build the application.
I am using C# and running on Windows10.
You really can't do that because Unity encodes the files into binary form and renames them too. You have to move the txt file after building then you can access it directly. I answered similar question like this yesterday so I will post the link to the answer. Do do things I mentioned in this answer below.
Unity3D loading resources after build
Then remove the Texture2D stuff and replace File.ReadAllBytes(imagePath); with System.IO.File.ReadAllLines(data.path); and that should work.
This is the problem of using Relative path or using absolute path.
If absolute path doesn't work try relative path.
eg.
../name.txt
put your name.txt in asset or somewhere you can point with.
If your texts are static (never more, never less) then you could simply use TextAsset : http://docs.unity3d.com/ScriptReference/TextAsset.html
Make prefabs from text assets;
Put the prefabs into your scene;
Let the user what prefab(s) to load text(s) from.

Cannot find a way to make tessnet2 work

I have created a console application.
Added a reference to tessnet2_32.
Ocr ocr = new Ocr();
using (Bitmap bmp = new Bitmap(filename))
{
tessnet2.Tesseract tessocr = new tessnet2.Tesseract();
tessocr.Init(#"C:\temp\tessdata", "eng", false);
...
I also tried changing "C:\temp\tessdata" to
C:\work\ConsoleApplication3\ConsoleApplication3
C:\work\ConsoleApplication3\ConsoleApplication3\tessdata
C:\work\ConsoleApplication3\ConsoleApplication3\bin\debug
C:\work\ConsoleApplication3\ConsoleApplication3\bin
C:\work\ConsoleApplication3\ConsoleApplication3\bin\debug\tessdata
C:\work\ConsoleApplication3\ConsoleApplication3\bin\tessdata
C:\work\ConsoleApplication3\ConsoleApplication3\debug\tessdata
C:\work\ConsoleApplication3\tessdata
C:\work\ConsoleApplication3\
The tessdata folder itself contained 9 failed and was added to all of these locations:
eng.cube.bigrams
eng.cube.fold
eng.cube.lm
eng.cube.bigrams
eng.cube.params
eng.cube.size
eng.cube.word-freq
eng.tesseract_cube.nn
eng.traineddata
But it just always exists at that .Init line with a message:
The file 'z:\dev\interne\cs\tesseract-ocr-svn\dotnet\tessnet2.cpp' does not exist.
I cannot imagine why it is trying to access some Z disk while I only have C. Or I just completely misunderstand the error.
Can someone be kind enough to post step by step telling what to do and/or what I am doing wrong? I feel completely lost even after reading 30+ google links.
You use the wrong version of language data file; what you have is for Tesseract 3.0x. tessnet2 is .NET wrapper for Tesseract 2.04, so you will need to load compatible data file.
Try download tesseract-2.00.eng.tar.gz from https://sourceforge.net/projects/tesseract-ocr-alt/files/.

C# import of Adobe Illustrator (.AI) files render to Bitmap?

Anyone knows how to load a .AI file (Adobe Illustrator) and then rasterize/render the vectors into a Bitmap so I could generate eg. a JPG or PNG from it?
I would like to produce thumbnails + render the big version with transparent background in PNG if possible.
Ofcause its "possible" if you know the specs of the .AI, but has anyone any knowledge or code to share for a start? or perhaps just a link to some components?
C# .NET please :o)
Code is most interesting as I know nothing about reading vector points and drawing splines.
Well, if Gregory is right that ai files are pdf-compatible, and you are okay with using GPL code, there is a project called GhostscriptSharp on github that is a .NET interface to the Ghostscript engine that can render PDF.
With the newer AI versions, you should be able to convert from PDF to image. There are plenty of libraries that do this that are cheap, so I would choose buy over build on this one. If you need to convert the older AI files, all bets are off. I am not sure what format they were in.
private void btnGetAIThumb_Click(object sender, EventArgs e)
{
Illustrator.Application app = new Illustrator.Application();
Illustrator.Document doc = app.Open(#"F:/AI_Prog/2009Calendar.ai", Illustrator.AiDocumentColorSpace.aiDocumentRGBColor, null);
doc.Export(#"F:/AI_Prog/2009Calendar.png",Illustrator.AiExportType.aiPNG24, null);
doc.Close(Illustrator.AiSaveOptions.aiDoNotSaveChanges);
doc = null; //
}
Illustrator.AiExportType.aiPNG24 can be set as JPEG,GIF,Flash,SVG and Photoshop format.
I Have Tested that with Pdf2Png and it worked fine with both .PDF and .ai files.
But I don't know how it will work with transparents.
string pdf_filename = #"C:\test.ai";
//string pdf_filename = #"C:\test.pdf";
string png_filename = "converted.png";
List<string> errors = cs_pdf_to_image.Pdf2Image.Convert(pdf_filename, png_filename);

How do I get a Video Thumbnail in .Net?

I'm looking to implement a function that retrieves a single frame from an input video, so I can use it as a thumbnail.
Something along these lines should work:
// filename examples: "test.avi", "test.dvr-ms"
// position is from 0 to 100 percent (0.0 to 1.0)
// returns a bitmap
byte[] GetVideoThumbnail(string filename, float position)
{
}
Does anyone know how to do this in .Net 3.0?
The correct solution will be the "best" implementation of this function.
Bonus points for avoiding selection of blank frames.
I ended up rolling my own stand alone class (with the single method I described), the source can be viewed here. Media browser is GPL but I am happy for the code I wrote for that file to be Public Domain. Keep in mind it uses interop from the directshow.net project so you will have to clear that portion of the code with them.
This class will not work for DVR-MS files, you need to inject a direct show filter for those.
This project will do the trick for AVIs: http://www.codeproject.com/KB/audio-video/avifilewrapper.aspx
Anything other formats, you might look into directshow. There are a few projects that might help:
http://sourceforge.net/projects/directshownet/
http://code.google.com/p/slimdx/
1- Get latest version of ffmpeg.exe from : http://ffmpeg.arrozcru.org/builds/
2- Extract the file and copy ffmpeg.exe to your website
3- Use this Code:
Process ffmpeg;
string video;
string thumb;
video = Server.MapPath("first.avi");
thumb = Server.MapPath("frame.jpg");
ffmpeg = new Process();
ffmpeg.StartInfo.Arguments = " -i "+video+" -ss 00:00:07 -vframes 1 -f image2 -vcodec mjpeg "+thumb;
ffmpeg.StartInfo.FileName = Server.MapPath("ffmpeg.exe");
ffmpeg.Start();
There are some libraries at www.mitov.com that may help. It's a generic wrapper for Directshow functionality, and I think one of the demos shows how to take a frame from a video file.
This is also worth to see:
http://www.codeproject.com/Articles/13237/Extract-Frames-from-Video-Files

Categories