BitMiracle Tiff.ClientOpen() Fails - c#

I am trying to open an image byte array with the Tiff.ClientOpen method as follows:
using (MemoryStream ms = new MemoryStream(img))
{
using (Tiff input = Tiff.ClientOpen("InMemory", "r", ms, new TiffStream()))
{
}
}
Where img = byte[].
But inside my second 'using' input = null. I am 100% sure img has data, and stepping through the debug process it even worked a few times.
Has anyone experienced this?

Seems like the issue is with the format of the tiff I am reading into the memory stream. By using the library to create a tiff as shown in the example here:
https://bitmiracle.github.io/libtiff.net/?topic=html/e4f25423-eede-4ef6-a920-9cb539d056c6.htm
then passing the result of that to the memory stream, after that then the ClientOpen() works. Not sure why. This is when you wish BitMiracle provided support ;).

Replace InMemory with in-memory, and make sure you selected a valid image.
using (Tiff image = Tiff.ClientOpen("in-memory", "r", ms, new TiffStream()))

Related

Image as byte array to Stream

I am taking pictures with my camera and when OnPictureTaken is called i get a byte[ ] data. I am trying to convert the byte array to a System.IO.Stream. This helps me to analise the image in the Project Oxford API. I've tried in countless ways to do this but it seems I can't find a solution. I would be very grateful if you help me.
You can use the MemoryStream class, which creates a stream backed by a byte array: MSDN link
When using the Client SDK, wich you can get via NuGet, you need to provide a Stream to methods like VisionServiceClient.AnalyzeImageAsync().
You can create a Stream out of an byte[] and provide it to the SDK like this:
using (var stream = new MemoryStream(yourByteArray))
{
var visionServiceClient = new VisionServiceClient("YOUR_API_KEY");
var visualFeatures = new VisualFeature[] { VisualFeature.Adult, VisualFeature.Categories, VisualFeature.Color, VisualFeature.Description, VisualFeature.Faces, VisualFeature.ImageType, VisualFeature.Tags };
var result = await visionServiceClient.AnalyzeImageAsync(stream, visualFeatures);
}
Hint: In Android you often end up with a Android.Graphics.Bitmap object when working with images. Especially when taking pictures with the camera. You can also convert them to streams with imageBitmap.Compress(Bitmap.CompressFormat.Jpeg, 0, stream); but don't forget to "rewind" the stream with stream.Seek(0, SeekOrigin.Begin);, otherwise the SDK will throw an exception.

Raspberry Pi and framebuffer input with mono

I'm trying to render a bitmap in Memory using mono. This image should be displayed on Adafruits 2.8" touch TFT (320*240). The Programm is developed with Visual Studio 2013 Community Edition. I want to host a ASP.NET Web Api and Show
some data on the Display. The ASP.NET part is working fine and the image is rendered. My idea was to write the Image to the framebuffer Input, but doing this I get an Exception saying that file is to large. I'm just writing raw data without BMP Header. Has someone managed doing this? Maybe creation of image is
wrong.
It seems as something is happening because the display changes and I can see white areas which might be from my image.
I don't want to use any extra libraries to keep it simple. So my idea is to use FBI directly. Does anyone know this problem and the solution?
Here is some of my code:
using (Bitmap bmp = new Bitmap(240, 320, PixelFormat.Format16bppRgb555))
{
[...]
Byte[] image = null;
using(MemoryStream memoryStream = new MemoryStream())
{
bitmap.Save(memoryStream, ImageFormat.Bmp);
Byte[] imageTemp = memoryStream.GetBuffer();
//Remove BMP header
image = new Byte[imageTemp.Length - 54];
Buffer.BlockCopy(imageTemp, 54, image, 0, image.Length);
//153600 byte
using (FileStream fb1 = new FileStream("/dev/fb1", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
fb1.Write(image, 0, image.Length);
fb1.Close();
}
}
}
Take a look at http://computerstruggles.blogspot.de/2013/02/how-to-program-directfb-in-c-on.html - the idea is to install the directfb library and use it from C# with PInvoke. The blog's author uses a mini wrapper in C to make using it even easier. BTW why don't you like to install additional libraries and to profit from the work others have done for you?
You may be running out of memory when the MemoryStream reallocates memory. When it needs to grow, it doubles in size. With this large of a write, the internal buffer is probably exceeding available memory. See Why does C# memory stream reserve so much memory? for more information.

MemoryStream (pdf) to Ghostscript to MemoryStream (jpg)

I did see "PDF to Image using GhostScript. No image file has to be created", but that only (sort of) answered half my question. Is it possible to use GhostScriptSharp (or the regular GhostScript dll) to convert a pdf in a MemoryStream to a jpg in a MemoryStream? I speak of a dynamically filled in pdf form with iTextSharp which I am already directing to a MemoryStream to save to a database or stream to a http response, and I'd really love to avoid saving to a file (and subsequent cleanup) if I can.
The sole answer in the answer I referenced claimed that one has to go down to the GhostScript dll to do the latter part, but it was obvious I would need to do a good bit of leg-work to figure out what that meant. Does anyone have a good resource that could help me on this journey?
The thing is that the PDF language, unlike the PostScript language, inherently requires random access to the file. If you provide PDF directly to Standard Input or via PIPE, Ghostscript will copy it to a temporary file before interpreting the PDF. So, there is no point of passing PDF as MemoryStream (or byte array) as it will anyway end up on the disk before it is interpreted.
Take a look at the Ghostscript.NET and it's GhostscriptRasterizer sample for the 'in-memory' output.
Ghostscript.Net is a wrapper to the Ghostscript dll. It now can take a stream object and can return an image that can be saved to an stream. Here is an example that I used on as ASP page to generate PDF's from a memory stream. I haven't completely figured out the best way to handle the ghostscript dll and where to locate it on the server.
void PDFToImage(MemoryStream inputMS, int dpi)
{
GhostscriptRasterizer rasterizer = null;
GhostscriptVersionInfo version = new GhostscriptVersionInfo(
new Version(0, 0, 0), #"C:\PathToDll\gsdll32.dll",
string.Empty, GhostscriptLicense.GPL);
using (rasterizer = new GhostscriptRasterizer())
{
rasterizer.Open(inputMS, version, false);
for (int i = 1; i <= rasterizer.PageCount; i++)
{
using (MemoryStream ms = new MemoryStream())
{
Image img = rasterizer.GetPage(dpi, dpi, i);
img.Save(ms, ImageFormat.Jpeg);
ms.Close();
AspImage newPage = new AspImage();
newPage.ImageUrl = "data:image/png;base64," + Convert.ToBase64String((byte[])ms.ToArray());
Document1Image.Controls.Add(newPage);
}
}
rasterizer.Close();
}
}

How to display a PNG from a file?

I want to switch the image that is displayed on a toolStripButton. But I juste can't find how to do that.
I think it should be something like:
btSearch.Image = new Image("myimage.png");
But it doesn't work ( new Image seems not to exist).
Thank you for your help
Use Image.FromFile():
btSearch.Image = Image.FromFile("myimage.png");
Unfortunately, the file will be locked until you dispose the image. For another solution, see the question, ToolStripButton: what's wrong with assigning an image programmatically.
I recommend the Image.FromStream() method as it doesn't lock the actual file.
For example:
using (var stream = File.OpenRead(path))
using (var image = Image.FromStream(stream))
{
//Black magic here.
}
Note that you must keep the stream open for the lifetime of the Image. The stream is reset to zero if this method is called successively with the same stream.
Here's a previous discussion with an answer from Jon Skeet.

Image.FromStream(PostedFile.InputStream) Fails. (Parameter is not valid.) (AsyncFileUpload))

I'm using an AsyncFileUpload (AJAX Toolkit) to upload images.
I have a Button which handle the image resizing.
This have worked fine for some time, but not anymore...
protected void BtnUploadImage_Click(object sender, EventArgs e)
{
var imageFileNameRegEx = new Regex(#"(.*?)\.(jpg|jpeg|png|gif)$",
RegexOptions.IgnoreCase);
if (!AsyncFileUpload1.HasFile ||
!imageFileNameRegEx.IsMatch(AsyncFileUpload1.FileName))
{
AsyncFileUpload1.FailedValidation = true;
ErrorLabel.Visible = true;
return;
}
ErrorLabel.Visible = false;
var file = AsyncFileUpload1.PostedFile.InputStream;
var img = Image.FromStream(file, false, false);
...
}
Another thing which I find weird: If I try a image which is smaller than 80kb it works..!
We have tried to restart the server, but no change.
Same code runs fine on my machine. (heard that before ?? :) )
I also tried to save the file on the server, then to get the file trough Image.FromFile(), but then I get "Cannot access a closed file."
How to resolve this ?
I would make sure the stream is positioned at the start:
var file = AsyncFileUpload1.FileContent;
file.Seek(0, SeekOrigin.Begin);
var img = Image.FromFile(file);
Second thing to check: the requestLengthDiskThreshold setting. Unless specified this setting has a default of ... yes, 80 KB.
Note: imo there should be no overall difference whether you use Image to read the file stream directly or if you use an intermediate MemoryStream (other than the fact that in the latter case you actually loads the entire file into memory twice). Either way the original file stream will be read from, thus stream position, CAS rights, file permissions, etc still applies.
Note2: and yes, by all means make sure those resources are disposed properly :)
This is correct, it will not work. The problem is that you are crossing a managed/unmanaged boundary, I recently encountered the same. Other problems are that the stream is not directly there and the Image.FromStream has no idea how to deal with it.
The solution is quite straightforward: read everything from PostedFile into a MemoryStream (just use new MemoryStream()) and use the MemoryStream with the Image.FromStream. This will solve your problem.
Make sure to make proper use of using when you work with Image, Graphics and Streams. All of them implement the IDisposable and in an ASP.NET environment, not using using blocks properly, can and will lead to increased memory usage and other nasty side effect on the long run (and ASP.NET apps do run very long!).
The solution should look something like this:
using(Stream memstr = new MemoryStream())
{
// copy to a memory stream
Stream uploadStream = AsyncFileUpload1.PostedFile.InputStream;
byte[] all = new byte[uploadStream.Length];
uploadStream.Read(all, 0, uploadStream.Length);
memstr.Write(all, 0, uploadStream.Length);
memstr.Seek(0, SeekOrigin.Begin);
using(Graphics g = Graphics.FromStream(memstr))
{
// do your img manipulation, or Save it.
}
}
Update: the crossing managed boundary issue only occurs in the reverse (using Response stream), it seems, not with Upload streams, but I'm not entirely sure.

Categories