Handle lots of images in C# application - c#

I'm trying to create a card game in C# and for this I have alot of images that I need to load. They're all jpg images and there are about 7000 of them.
I would like to make sure that if you download the game, the images will not be easily accessible, meaning that they should not just be JPG images in a sub folder of the application. So I thought about imbedding them in a DLL file.
But how do I do this? And how do I handle this efficiently? Is there a tecnique to this sort of thing, or is another method preferable?

I would like to make sure that [...] the images will not be easily accessible
First, you should ask yourself why you want to forbid this. If you just want to avoid that someone else manipulates the pictures, you can leave them in a bunch of subfolders as JPGs, just generate checksums for each file and check them at the time the program loads the pictures.
If you want to avoid reuse of the pictures, you can leave them in a bunch of subfolders, but not as JPGs. Encode them with for example with the standard AES algorithm. But beware, that won't prevent anyone else of making screenshots while you application is running, so you should consider if that's really worth the effort.
EDIT: if you want to embed the images because installation gets easier when you have just one big file to deploy instead of 7000 single files, then you may write a helper program for creating resource files programmatically. See this page from Microsoft, especially the part about .resource files, to learn how to utilize the ResourceWriter class for that purpose.

If you have 7000 image, you need a database. Microsoft SQL Server Compact 4.0 is an option. It's small and easy to use.

I'm assuming that this is a windows application
In order to Embed a Image to the assembly
1. Right click the Image file and Select properties
2. In the Properties Pane Set the BuildAction as Embeded resource
So this Image becomes a embeded resource when the application is compiled
Then you can access the Image from the assembly like:
global::[[MyNameSpace]].Properties.Resources.[[ImageName]]
for eg:this.pictureBox1.Image = global::[[MyNameSpace]].Properties.Resources.[[ImageName]]

Related

How can I search for all non-resource image (paths) on a drive?

I want to write a program that gathers all pictures that someone may have on their computer, while ignoring any resource files (i.e. a .jpg for a game icon, for a game in their Program Files, etc.)
What can I research/learn about for accomplishing this?
Is there some sort of meta-data that can be tied to user-generated pictures, etc?
I want to start with .jpg/.jpeg files at first, but eventually I'd like to include:
Any Camera files that were uploaded and saved to the computer.
Any picture that was downloaded from the internet and saved.
files from image creation/editing tools such as aseprite or photoshop and saved.
Any help is appreciated and any criticism is accepted.
Thank you in advance for your direction.
Edit: For a use case example, I'd like to be able to search through a drive for pictures that a user has, that they may not remember where they saved them.
There is no reliable way to know if a image is intended to be used as a resource. Programs can be stored anywhere on the drive, so using the path will not be reliable. And images from the internet may have arbitrary metadata.
My suggestion would be to find all images (note that this will take some time), and use some heuristic to guess what folders represent an image archive. Presumably most people would store photos in one or a few different folders. If all subfolders mostly contain image files, and no files like .exe or .dll files, it would be a good candidate. But you should probably ask the user to confirm the folder selection and allow for changes.
Note that things like cached internet images would probably not be included since they will be mixed in with other types of cached data.

Can I open an image in Windows Photo Viewer without path to the image

I'm encrypting and decrypting images because they contain sensitive information.
My struggle here is that I cant do the standard Process.Start(saveImagePath); because the of the encryption.
So far my solution is to just make a Windows Form that opens it in PictureBox because it doesn't require a path and I can just do this:
newImage = enc.Decrypt();
pictureBox1.Image =newImage;
But it's been a struggle trying to simulate Windows Photo Viewer.
My question is, can I open an image with just the image newImage = enc.Decrypt(); without the path in Windows Photo Viewer (or any other similar software), or am I doomed to try and replicate a Photo Viewer program?
Let me start by saying that if the images information is highly sensitive, then there is no way to display it to the user and ensure its security 100%. Even with a memory stream, one can make a memory dump and access the sensitive info. That's not trivial, but doable.
Now that's out of the way, Windows processes cannot directly access each other's memory without going through privileged debug-like API functions like ReadProcessMemory. This is what keeps Windows stable and secure, but makes what you are trying to accomplish not doable. You have to use a file.
Others suggested saving the file in the Windows Temporary folder. That's not any more secure than saving it in any other folder like you're doing. A little more secure way is to create a RAM-Disk, save the files there, display them, and then remove the RAM-Disk.
The RAM-Disk is an in-memory simulation of a hard-disk and you can access it in the same way with a drive letter. Creating and then removing a RAM-Disk isn't a trivial task, and it only offers a little more security, but you're the only one who can decide whether it is worth it. The user can still see and access the files on the RAM-Disk, but only before it is removed. So the only added security it offers is reducing the window during which the user can directly access the files.
Opening the images in your own app like you're doing is still the most secure way, as the only way to extract those files is by making a memory dump, and that's really hard with images (it's easier with text). You can search for some library if you don't want to code it all by yourself.

Reading font file content in winrt

How to read font file stream from WinRT platform? I need to get font file content from C# UWP. As far as you probably know there is no way to read files from Fonts folder directly. FilePicker is also not an option for me, since it's not a user responsibility to choose this folder. I found the way to enumerate font names using DirectWrite (C++) and then wrapping it with COM component which will be available in C# (https://code.msdn.microsoft.com/FontExplorer-lets-you-f01d415e#content), I wonder if the similar thing can be done to read font file content as byte[] or Stream?
You cannot directly read the TTF file from a UWP app without the user navigating to the file manually. The UWP application is not allowed to open files without the user being prompted unless they are in specific locations.
Also, as mentioned in a comment, many fonts may not be distributed or embedded without special licenses.
Good news: PDF export doesn't make much sense in windows 10. Windows 10 has build-in PDF printer. So, it's better to kill 2 birds with one stone: implement printing and get PDF export free of charge.
Assuming you already got as far as you have created IDWriteFontFile instance, then it's easy to read arbitrary file fragment:
Get file reference key with IDwriteFontFile::GetReferenceKey();.
Get loader interface with IDWriteFontFile::GetLoader();
Create stream instance with IDWriteFontFileLoader::CreateStreamFromKey() using key from step 1.
Use IDWriteFontFileStream::ReadFileFragment/ReleaseFileFragment to read from file stream to your buffer.

How to load user generated png images as textures (not xnb's)?

The idea is to let users create their own textures, put them in a folder as images (and maybe set some properties in a separate text file) for the game to load and work accordingly.
Usually I have my own textures as images, they are processed by Visual Studio when compiling, and then the game uses XNB files. But how about end users that don't have VS installed?
UPD: The only safe option (that doesn't require manual resource disposal) seems to be replacing the original resource files in XNB format. For that, you can process your own PNG, WAV and other files with this tool from codeplex and put them in content folder of the game.
if you works in windows only... (not xbox and not windows phone)
you can use Texture2d.FromStream(File.OpenRead(path));
You have to realize that this way, you should call the texture dispose method when the texture is not needed to free resources.
Wehn you use the content manager, is the manager who call the method when the game ends.

What's the simplest way to embed (new) file information in a drag?

I want users to be able to drag elements from my program onto the desktop to create files from them. What's the simplest way to embed this information into a DataObject so explorer will accept drops and create the appropriate file(s)?
My experience with drag and drop is limited, and so far the only way I can think of is to actually create the files in a temporary directory and attach their paths to the DataObject via a DataFormat of "FileDrop"... but there must be a better way.
Basically what I understand you want to do is drag a non-existent file from your application to explorer and have a physical file created.
Well, your solution of creating a temporary file and then setting that in the DataObject is probably the short cut solution.
The "correct" solution, without creating a temporary disk file will require significant amount of P/Invoke type interop to create a custom IDataObject that can render the file descriptor and content from memory rather than a physical source file. I have not done this in .NET, but I can guess it would be a fair amount of work.

Categories