I'm trying to get an image in the resources as a byte[] for insertion into a database. The resource is at Resources/CatSeal and is a file called index.jpg.
I've looked at this question, but I'm still having trouble. I'm getting a NullReferenceException on the indicated line. My namespace is DatabaseConnectionTests. According to this documentation, under "Access Resources" it should follow this format, which I believe I'm doing:
MyNameSpace.MyImage.bmp
Here's my code:
Stream sourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("DatabaseConnectionTests.index.jpg");
using (var memoryStream = new MemoryStream())
{
sourceStream.CopyTo(memoryStream); // NullReferenceException here
seal.SealerImage = memoryStream.ToArray();
}
sealDatabaseOperations.Insert(seal);
How can I resolve this so that my resource image is loaded to a byte[]? Thanks in advance.
Looks like it's not finding your resource.
Try: "DatabaseConnectionTests.Resources.index.jpg"
Set a breakpoint in a class in the same assembly and evaluate this:
this.GetType().Assembly.GetManifestResourceNames()
That will list all resource names avail for that assembly.
Related
Having a code that works for ages when loading and storing images, I discovered that I have one single image that breaks this code:
const string i1Path = #"c:\my\i1.jpg";
const string i2Path = #"c:\my\i2.jpg";
var i = Image.FromFile(i1Path);
i.Save(i2Path, ImageFormat.Jpeg);
The exception is:
System.Runtime.InteropServices.ExternalException occurred
A generic error occurred in GDI+.
at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
at System.Drawing.Image.Save(String filename, ImageFormat format)
at ...
As far as I can see, there is nothing special about the image. It is approx 250 pixels in size and can be opened in e.g. Windows Image Viewer or Paint.NET:
(Since the image above, after being uploaded to Stack Overflow does not produce the error anymore, I've put the original image here)
What I discovered is that upon calling the Save method, the destination image file is being created with zero bytes.
I am really clueless on what causes the error.
My questions:
Can you think of any special thing that would hinder .NET from saving the image?
Is there any way (beside panicing) to narrow down these kind of errors?
While I still did not find out the reason what exactly caused the error when saving the image, I found a workaround to apply:
const string i1Path = #"c:\my\i1.jpg";
const string i2Path = #"c:\my\i2.jpg";
var i = Image.FromFile(i1Path);
var i2 = new Bitmap(i);
i2.Save(i2Path, ImageFormat.Jpeg);
I.e. by copying the image internally into a Bitmap instance and saving this image instead of the original image, the error disappeared.
I'm assuming that by copying it, the erroneous parts the caused the original Save call to fail are being removed an/or normalized, thus enabling the save operation to succeed.
Interestingly, the so stored image has a smaller file on disk (16 kB) than its original source (26 kB).
First of all make sure, that the desired folder has Read/Write permissions. Changing the permissions solved this problem for me.
Solution is here, you must dispose image object to release the memory on the server.
Try use using statement. Make sure destination directory on server exists too.
The reason may be that the image is loaded lazily and the loading process is not yet finished when you try to save it.
Following what's said in this blog post (assuming you're German by the picture you linked in your question) provides a possible solution. Also this SO question's accepted answer indicates this is due to the fact the image file you're trying to save to is locked.
EDIT
For Ulysses Alves, from the linked blog entry: If you load an image using Image.FromFile() it remains locked until it is disposed of. This prevents calls to Save().
pictureBox1.Image = Image.FromFile("C:\\test\\test1.jpg");
pictureBox1.Image.Save("C:\\test\\test2.jpg");
The above code throws an error.
To make it work, you need to copy the image. The following code works:
pictureBox1.Image = Image.FromFile("C:\\test\\test1.jpg");
Image copy = pictureBox1.Image;
copy.Save("C:\\test\\test2.jpg")
I found this question because I also faced the similar error and the file was actually created with zero length (if you don't see any file, first check the permissions to write into folder as other answers suggest). Although my code was slightly different (I use stream to read the image from memory, not from file), I think my answer may be helpful to anyone facing similar problem.
It may looks counter-intuitive, but you can't really dispose memory stream until you finish with image.
NOT WORKING:
Image patternImage;
using (var ms = new MemoryStream(patternBytes)) {
patternImage = new Bitmap(ms);
}
patternImage.Save(patternFile, ImageFormat.Jpeg);
Just don't dispose the stream until you done with image.
WORKS:
using (var ms = new MemoryStream(patternBytes)) {
patternImage = new Bitmap(ms);
patternImage.Save(patternFile, ImageFormat.Jpeg);
}
What is misleading:
Error message doesn't really tell you anything
You can see the image properties, like width and height, but can't
save it
my solution was to make, write temp content (File.WriteAllText) just before saving the file
Here is the code:
var i = Image.FromFile(i1Path);
File.WriteAllText(i2Path, "empty"); // <---- magic goes here
i.Save(i2Path, ImageFormat.Jpeg);
Please try and let me know
In my case I have accidentally deleted the directory where image was getting stored.
Key Information:
// Using System.Drawing.Imaging:
new Bitmap(image).Save(memoryStream, ImageFormat.Jpeg);
You MUST Cast the Image to a Bitmap to Save it.
Using:
// Using System.Drawing.Imaging:
image.Save(memoryStream, ImageFormat.Jpeg);
WILL throw the Error:
Generic GDI+ error when saving an image
Just use the visual studio as administrator or run the application created by the code as administrator it should work smoothly.
It is user access rights issue.
I faced the same and resolved it by running visual studio as administrator.
In my case, I set validateImageData to false:
Image.FromStream(stream, validateImageData: false);
solution:
Image.FromStream(stream, validateImageData: true);
Open in the program
const string i1Path = #"c:\my\i1.jpg";
const string i2Path = #"c:\my\i2.jpg";
var i = Image.FromFile(i1Path);
i.Save(i2Path, ImageFormat.Jpeg);
i.Dispose();
I have a problem. I am trying to load an image, so I use this code:
string resourceID = "MyApp.Templates.Good_Question.png";
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream(resourceID))
{
bitmap = SKBitmap.Decode(stream);
}
But it gives an error on stream, because stream is null. Now I created a folder in the root of the app called Templates and placed an image called Good_Question.png in the folder.
Why is my stream null?
I found it, I had to set the Build Action to Embedded Resource, not Resource
Spreadsheet output of OpenXML works in Excel (and Google Docs) but throws a runtime error in OpenOffice 4.x...
Specific error is
General Error.
General input/output error.
with no further explanation. It, in practice, has only occurred for me if there were greater than 40 rows for the spreadsheet; however, there did not seems to be a specific number of rows that caused the issue.
I have already created a workaround for the issue. This post is just to share my horrible, horrible solution for those that just need something.
I suspect the cause might be in the Zip headers or part of the zip entries themselves and that their is either a bug in the library that writes the Zip output for the System.IO.Packaging namespace (which I assume that OpenXML uses) or that OpenOffice has a very simple zip reader. Maybe something with the central directory file offsets versus the compressed file size, but I did not bother to check as I had limited time.
I may investigate further one day, or if anyone knows a quick solution, then do let me know. The files are written using the examples found on MSDN and they do open correctly in Excel.
In the meantime, if anyone needs a band-aid to the issue, I am posting my quick fix here since I was unable to find one myself. It expects a byte array (perhaps dumped from MemorySteam or read a FileStream). It outputs another byte array.
Someone clever could have it accept a Stream, seek to 0 relative to Beginning, and then read from there, perhaps writing directly to another passed in stream. That would be an exercise to the reader, unless someone happens to post a response that does the same.
If anyone does have a better solution, I would not mind knowing.
Uses .NET 4.5
References System.IO.Compression
using System;
using System.IO;
using System.IO.Compression;
namespace redmasq {
public static class ExcelFileFixExample {
public static byte[] XLSXOpenOfficePackageFix(byte[] fileData) {
using (MemoryStream ms = new MemoryStream(fileData, false)) {
using (ZipArchive za = new ZipArchive(ms)) {
using (MemoryStream ms2 = new MemoryStream()) {
using (ZipArchive za2 = new ZipArchive(ms2, ZipArchiveMode.Create)) {
foreach (ZipArchiveEntry entry in za.Entries) {
ZipArchiveEntry zae = za2.CreateEntry(entry.FullName, System.IO.Compression.CompressionLevel.Optimal);
using (Stream src = entry.Open()) {
using (Stream dest = zae.Open()) {
src.CopyTo(dest);
}
}
}
}
return ms2.ToArray();
}
}
}
}
}
}
I use Magick.NET for processing files. And now I need convert raw image format (such as .dng, .3fr, .cr2, .raw, .ptx, etc.) to simple jpg for generating preview on the site. I found example in documentation here
but it's not working. I put dcraw.exe to Magick.NET dll's but always got error in this moment:
//code
using (var originalImg = new MagickImage(abspath))...
//text of error
InnerException = {"iisexpress.exe: FailedToExecuteCommand `dcraw.exe -6 -w -O \"C:/Users/A8F50~1.CHE/AppData/Local/Temp/magick-29445L9OLy_DVIQq.ppm\" \"C:/Users/A8F50~1.CHE/AppData/Local/Temp/magick-294458yvxz2HRaYX\"' (-1) # error/delegate.c/ExternalDelegateCommand/484"}
Message = "iisexpress.exe: UnableToOpenBlob 'C:/Users/A8F50~1.CHE/AppData/Local/Temp/magick-29445L9OLy_DVIQq.ppm': No such file or directory # error/blob.c/OpenBlob/2684"
Is anyone faced with such problem? I have no idea why this shit happens. I wasted a lot of time for this and I'll be glad if you'll help me with this problem
you have to use a FileStream object instead the file path... That will work for me.
Try this:
FileStream fileStream = new FileStream(#"C:\QRcodes\IMG_9540.CR2", FileMode.Open);
using (MagickImage magickImage = new MagickImage(fileStream))
{
byte[] imageBytes = magickImage.ToByteArray();
Console.WriteLine("bytes in image: " + imageBytes.Length);
Console.ReadKey();
}
greetings
Markus
This is not related to the file stream or actual physical path. you can call the MagickImage constructor with a physical path. The problem and the error message you received is that your code cannot find the file. It may be because of the permission or the way you pass the address of the file or any thing that prevent your code to reach the file.
One another things: Converting the MagickImage to ByteArray is highly time consuming and is heavy process in the system. If you try an image with 20000 pixels you will see the result.
I'm having some really weird problems trying to load a file pragmatically into my project to save to a local folder.
I can load the file fine in my .xaml code, as so:
<BitmapImage x:Key="Image" UriSource ="/Assets/Submandibular_oedema.jpg" />
And I can display that image on my page. However, when I try to load the image and use it in my xaml.cs code like this
uriMyFile = new Uri("/Assets/Submandibular_oedema.jpg", UriKind.RelativeOrAbsolute);
It cannot find the file and as a result, won't let me do anything with the URI.
For background, my aim is to get the image stream then save it to a local folder.
I know it'll be a stupid little problem, but I can't find any solutions to it.
Thanks!
Try full path (specify your project assembly)
uriMyFile = new Uri("/YourAssemblyName;component/Assets/Submandibular_oedema.jpg",UriKind.RelativeOrAbsolute);
Update after Starktastics comment:
I finally understood your problem: you need the Application.GetResourceStream method to retrieve a stream of your resource, read from that stream and write it to a file stream.
var streamResourceInfo = Application.GetResourceStream(uri);
var stream = streamResourceInfo.Stream;
var byteBuffer = new byte[stream.Length];
using (stream)
{
stream.Read(byteBuffer, 0, byteBuffer.Length);
}
using (var fileStream = new FileStream("photo.jpg", FileMode.Create))
{
fileStream.Write(byteBuffer, 0, byteBuffer.Length);
}
I've updated the solution that you can download here.
Original answer:
If you use a WPF application, make sure that the asset you added to your project is to Build Action 'Resource'. You can check that in the properties pane after you clicked the file.
In any case, your syntax for the URI is correct. I checked it in a small project myself and it works. You can download it here (DropBox link)
Feel free to leave a comment.
Try to use
uriMyFile=new Uri("ms-appx:///Assets/YourImage.png"));
This works for me while trying to show a diffrent map icon for each place.