asp.net c# convert filestream to image - c#

i have a filestream which im trying to convert into a image. i have the following code
FileStream imageFile = image["file"] as FileStream;
image is a map holding information on the image. please can some one direct me on what I should do next.

Image.FromStream will take a stream and return an image. Incidentally, if you use Bitmap.FromStream or Image.FromStream, or indeed any of these methods, they all return a Bitmap, so they can all be upcast to Bitmap from Image if you want them to be.

you can do the following:
int width = 128;
int height = width;
int stride = width / 8;
byte[] pixels = new byte[height * stride];
// Define the image palette
BitmapPalette myPalette = BitmapPalettes.Halftone256;
// Creates a new empty image with the pre-defined palette
BitmapSource image = BitmapSource.Create(
width,
height,
96,
96,
PixelFormats.Indexed1,
myPalette,
pixels,
stride);
FileStream stream = new FileStream("new.jpg", FileMode.Create);
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.FlipHorizontal = true;
encoder.FlipVertical = false;
encoder.QualityLevel = 30;
encoder.Rotation = Rotation.Rotate90;
encoder.Frames.Add(BitmapFrame.Create(image));
encoder.Save(stream);

Related

Using Graphics.DrawImage , changes the background of my transparent PNG images , to black

I've write this method to resize my images, but the returned image for my transparent PNG images, has a black background.
What is the solution?
I've tried Bitmap.MakeTransparent() and also Graphics.Clear() but couldn't solve my problem.
I've checked all related questions, but couldn't find any useful answer to my question.
public HttpResponseMessage ImageResizer(string path, int w,int h)
{
var imagePath = HttpContext.Current.Server.MapPath(path);
Bitmap image;
try
{
image = (Bitmap)System.Drawing.Image.FromFile(imagePath);
}
catch
{
HttpResponseMessage hrm = new HttpResponseMessage();
return hrm;
}
int originalWidth = image.Width;
int originalHeight = image.Height;
// New width and height based on aspect ratio
int newWidth = w;
int newHeight = h;
// Convert other formats (including CMYK) to RGB.
Bitmap newImage = new Bitmap(newWidth, newHeight, PixelFormat.Format24bppRgb);
// Draws the image in the specified size with quality mode set to HighQuality
using (Graphics graphics = Graphics.FromImage(newImage))
{
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var attribute = new ImageAttributes())
{
attribute.SetWrapMode(WrapMode.TileFlipXY);
// draws the resized image to the bitmap
graphics.DrawImage(image, new Rectangle(0, 0, newImage.Width, newImage.Height), new Rectangle(0, 0, originalWidth, originalHeight), GraphicsUnit.Pixel);
}
}
// Get an ImageCodecInfo object that represents the PNG codec.
ImageCodecInfo imageCodecInfo = this.GetEncoderInfo(ImageFormat.Png);
// Create an Encoder object for the Quality parameter.
Encoder encoder = Encoder.Quality;
// Create an EncoderParameters object.
EncoderParameters encoderParameters = new EncoderParameters(1);
// Save the image as a PNG file with quality level.
EncoderParameter encoderParameter = new EncoderParameter(encoder, 10);
encoderParameters.Param[0] = encoderParameter;
var splitPath = imagePath.Split('.');
string newPath = splitPath[0] + "ss5.png";
newImage.Save(newPath, ImageFormat.Png);
MemoryStream memoryStream = new MemoryStream();
newImage.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
HttpResponseMessage response = new HttpResponseMessage();
response.Content = new ByteArrayContent(memoryStream.ToArray());
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/png");
response.Content.Headers.ContentLength = memoryStream.Length;
return response;
}
private ImageCodecInfo GetEncoderInfo(ImageFormat format)
{
return ImageCodecInfo.GetImageDecoders().SingleOrDefault(c => c.FormatID == format.Guid);
}
You are using PixelFormat.Format24bppRgb in your Bitmap constructor. That format is limiting your bitmap to 3 channels: red, green, and blue. Because of this, the bitmap you are creating doesn't support alpha (a.k.a. transparency) and will default to a solid black image. When you draw an image with transparency in it, the alpha of that image will either be pre-multiplied or discarded, depending on its format.
If you want to save your new image with transparency, you need to declare it with PixelFormat.Format32bppArgb:
Bitmap newImage = new Bitmap(newWidth, newHeight, PixelFormat.Format32bppArgb);

Displaying TIF image using byte array to writeable bitmap(C#)

I've a byte array of a tiff image. I want to form 3 images from it,that i'll do later but the problem is i'm not able to display the original image as it is.
Here is my xaml:
<Image Grid.Row="0" Grid.Column="0" Name="ReferenceImage"/>
xaml.cs code:
public MainWindow()
{
InitializeComponent();
ImagePath = #"G:\TiffImage\Test.TIF"
DisplayAllImages();
}
private void DisplayAllImages()
{
byte[] imageSize = File.ReadAllBytes(ImagePath);
ReferenceImage.Source = DisplayAllImages(imageSize, 64, 64);
}
private WriteableBitmap DisplayAllImages(byte[] imageData,int height,int width)
{
if (imageData != null)
{
PixelFormat format = PixelFormats.Gray8;
WriteableBitmap wbm = new WriteableBitmap(height, width, 96, 96, format, null);
wbm.WritePixels(new Int32Rect(0, 0, height, width), imageData, 1*width, 0);
return wbm;
}
else
{
return null;
}
}
My main aim is to display image using byte array like this way only, so that i can extract byte array to form other image as per requirements.
The image file contains encoded bitmap data. In order to access the raw pixels you would first have to decode the bitmap:
BitmapSource bitmap;
using (var fileStream = new FileStream(ImagePath, FileMode.Open, FileAccess.Read))
{
bitmap = BitmapFrame.Create(
fileStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
Now you would get the raw pixels by calling the CopyPixels method of the BitmapSource:
var width = bitmap.PixelWidth;
var height = bitmap.PixelHeight;
var stride = (width * bitmap.Format.BitsPerPixel + 7) / 8;
var imageData = new byte[height * stride];
bitmap.CopyPixels(imageData, stride, 0);
I'm not getting the expected images.Although i'm able to generate images which is matching almost 75% but not completely.

WPF BitmapImage sliced in two

I'm messing about with Bitmaps in a WPF application. I receive the a byte array on a background thread and a converter changes it to a bitmapSource for binding.
However, if I try to directly create the bitmapSource in memory and display it, it splits the image into two. I'm haven't had a great deal of experience with bitmaps but enough so that I could always display images.
The weird thing, is that if I write the file out first, then read it back in, it works.
File.WriteAllBytes(#"C:\woot2.bmp", bytes);
var bmp = new BitmapImage(new Uri(#"C:\woot2.bmp"));
var height = bmp.Height; // 480.0
var width = bmp.Width; // 640.0
var format = bmp.Format; // Indexed8
var dpix = bmp.DpiX; // 96.0
var dpiY = bmp.DpiY; // 96.0
var pallete = bmp.Palette; // Gray256
var cacheOption = bmp.CacheOption; // Default
var createOptions = bmp.CreateOptions; // None
return bmp;
[
I've checked the height, width, pixelFormat, pixelPalette, dpi etc all match the file that I read in and it still displays it incorrectly. Even checked the header of the file.
I've tried BitmapImages, BitmapSources, WriteableBitmaps with PngBitmapEncoder and I still get the same. I feel like either i'm missing something fundamental or there's a bug. I thought the slice was wrong, but there's no skewing,
i'm displaying it in an image:
<Image Width="640" Height="480"
Source="{Binding VisionImage, Mode=OneWay,UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource VisionImageConverter} }"></Image>
Here's the code i've got to convert it currently
var width = 640;
var height = 480;
var dpiX = 96;
var dpiY = 96;
var pixelFormat = PixelFormats.Indexed8;
var palleteFormat = BitmapPalettes.Gray256;
var stride = 4* (((width*pixelFormat.BitsPerPixel) + 31)/32);
return BitmapSource.Create(width, height, dpiX, dpiY,
pixelFormat, palleteFormat, bytes, stride);
Any ideas?
Apparently the byte array does not contain raw pixel data, but an encoded BMP buffer, so you can't create a BitmapSource by BitmapSource.Create.
You should instead create a BitmapImage from the encoded BMP buffer like this:
var bitmapImage = new BitmapImage();
using (var stream = new MemoryStream(bytes))
{
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.StreamSource = stream;
bitmapImage.EndInit();
}
Or alternatively create a BitmapFrame like this:
BitmapFrame bitmapFrame;
using (var stream = new MemoryStream(bytes))
{
bitmapFrame = BitmapFrame.Create(stream,
BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
Okay, so the answer for this ended up being quite simple. Instead of giving it just the pixel array, I was giving it the whole bitmap file array. I think when you create a bitmapImage from a file it must use a bitmapDecoder internally. Which is why writing to a file and then reading it back worked.
So I could have calculated the pixel offset from the file and then copied the bytes that I needed, but I chose to wrap the array in a memorystream and use a BmpBitmapDecoder because it was simpler
using(var ms = new MemoryStream(bytes))
{
var decoder = new BmpBitmapDecoder(ms, BitmapCreateOptions.DelayCreation, BitmapCacheOption.OnDemand);
return new WriteableBitmap(decoder.Frames.FirstOrDefault());
}

Set image from bitmap

Image image = new Image ();
Bitmap bitmap = Bitmap.CreateBitmap (200, 100, Bitmap.Config.Argb8888);
Canvas canvas = new Canvas(bitmap);
var paint = new Paint();
paint.Color = Android.Graphics.Color.Red;
paint.SetStyle(Paint.Style.Fill);
Rect rect = new Rect(0, 0, 200, 100);
canvas.DrawRect(rect, paint);
Android.Widget.ImageView contains method SetImageBitmap.
What the best way to set Xamarin.Forms.Image from my bitmap?
Convert the Bitmap to byte[] via http://forums.xamarin.com/discussion/5950/how-to-convert-from-bitmap-to-byte-without-bitmap-compress
There are two solutions mentioned.
var byteArray = ByteBuffer.Allocate(bitmap.ByteCount);
bitmap.CopyPixelsToBuffer(byteArray);
byte[] bytes = byteArray.ToArray<byte>();
return bytes;
(in case first solution is still broken)
ByteBuffer buffer = ByteBuffer.Allocate(bitmap.ByteCount);
bitmap.CopyPixelsToBuffer(buffer);
buffer.Rewind();
IntPtr classHandle = JNIEnv.FindClass("java/nio/ByteBuffer");
IntPtr methodId = JNIEnv.GetMethodID(classHandle, "array", "()[B");
IntPtr resultHandle = JNIEnv.CallObjectMethod(buffer.Handle, methodId);
byte[] byteArray = JNIEnv.GetArray<byte>(resultHandle);
JNIEnv.DeleteLocalRef(resultHandle);
And then use
var image = new Image();
image.Source = ImageSource.FromStream(() => new MemoryStream(byteArray));
to create an Image.
I tried #Wosi's answer, but for some reason the rendering of the image after that didn't work and the code is specific to Android. I needed to work from a byte array to a bitmap and then back again. This is what I did:
Code for turning a bitmap into a byte array:
byte[] bitmapData;
using (var stream = new MemoryStream())
{
tempBitmap.Compress(Android.Graphics.Bitmap.CompressFormat.Png, 0, stream);
bitmapData = stream.ToArray();
}
And the code for turning a byte array into a bitmap:
Android.Graphics.Bitmap tempBitmap = Android.Graphics.BitmapFactory.DecodeByteArray(imageByteArray, 0, imageByteArray.Length, options);
Where "options" is defined as follows:
Android.Graphics.BitmapFactory.Options options = new Android.Graphics.BitmapFactory.Options
{
InJustDecodeBounds = true
};
Android.Graphics.Bitmap result = Android.Graphics.BitmapFactory.DecodeByteArray(bitmapArray, 0, byteArrayLength, options);
//int imageHeight = options.OutHeight;
//int imageWidth = options.OutWidth;
In this part the Bitmap gets decoded. This is done to get the image height and width properties. For my case I required this information to encode it as a byte array again.
There with this it is possible to encode a byte array to a string and then back again.
Setting an image source from a byte array is done as follows:
var imageSource = ImageSource.FromStream(() => new MemoryStream(ImageByteArray, 0, ImageByteArray.Length));

read jpg, resize, save as png in WPF application c# or vb.net

Going bonkers here trying to do this in WPF (with all the new image manipulation tools), but can't seem to find a working solution. So far, all the solutions are drawing them on the screen or making multiple saves, but I need to do this completely in memory.
Basically, I want to load a large jpeg into memory, resize it smaller (in memory), save as a small PNG file.
I can load the jpeg file into a BitMap object, fine. after that, I'm stumped.
I found this function that looks like it does the trick but it requires an ImageSource (unfortunately, I can't find a way to convert my in-memory BitMap object to an ImageSource that does not yield a NULL exception.)
private static BitmapFrame CreateResizedImage(ImageSource source, int width, int height, int margin)
{
dynamic rect = new Rect(margin, margin, width - margin * 2, height - margin * 2);
dynamic #group = new DrawingGroup();
RenderOptions.SetBitmapScalingMode(#group, BitmapScalingMode.HighQuality);
#group.Children.Add(new ImageDrawing(source, rect));
dynamic drawingVisual = new DrawingVisual();
using (drawingContext == drawingVisual.RenderOpen())
{
drawingContext.DrawDrawing(#group);
}
// Resized dimensions
// Default DPI values
dynamic resizedImage = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Default);
// Default pixel format
resizedImage.Render(drawingVisual);
return BitmapFrame.Create(resizedImage);
}
With WPF it's as easy as this:
private void ResizeImage(string inputPath, string outputPath, int width, int height)
{
var bitmap = new BitmapImage();
using (var stream = new FileStream(inputPath, FileMode.Open))
{
bitmap.BeginInit();
bitmap.DecodePixelWidth = width;
bitmap.DecodePixelHeight = height;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
}
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmap));
using (var stream = new FileStream(outputPath, FileMode.Create))
{
encoder.Save(stream);
}
}
You may consider to only set one of DecodePixelWidth and DecodePixelHeight in order to preserve the original image's aspect ratio.

Categories