I have a c# tcp server and i send a image byte array to my android client. But i have no success to convert array to bitmap.
This is my c# code:
new Thread(() =>{
//İmage converter
ImageConverter imConv = new ImageConverter();
//memory streaö
MemoryStream ms = new MemoryStream();
//bitmap
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format16bppRgb555);
Graphics g = Graphics.FromImage(bitmap);
g.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
Cursors.Default.Draw(g, new Rectangle(new Point(Cursor.Position.X, Cursor.Position.Y), new Size(Cursors.Default.Size.Width, Cursors.Default.Size.Height)));
bitmap.Save(ms, ImageFormat.Png);
Image img = Image.FromStream(ms);
byte[] imgArry = (byte[])imConv.ConvertTo(img,typeof(byte[]));
tcpManager.SendTo(socket,imgArry);
bitmap.Dispose();
ms.Close();
ms.Dispose();
Thread.Sleep(41);
}).Start();
And this is my android client code, i get successfully the byte array but the function returns me a null bitmap
#Override
public void OnReceived(byte[] byteData) {
try{
final Bitmap bitmap = BitmapFactory.decodeByteArray(byteData, 0, byteData.length);
runOnUiThread(new Runnable() {
#Override
public void run() {
screenView.setImageBitmap(bitmap);
}
});
}catch (Exception ex){
}
}
Related
I want to share bitmap between server and client. I've tried a lot, but I've had problems with all the way the bottom part of the image missing.
First way:
Bitmap bmp = new Bitmap(800, 450);
using (var ms = new MemoryStream(readBuffer))
{
bmp = new Bitmap(ms);
}
Second way:
using (var ms = new MemoryStream(readBuffer))
{
bmp = new Bitmap(ms);
//bmp = Image.FromStream(ms) as Bitmap;
}
This way, the image wasn't converted properly.
Bitmap bmp = new Bitmap(800, 450, PixelFormat.Format24bppRgb);
BitmapData bmpData = bmp.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.WriteOnly, bmp.PixelFormat);
Marshal.Copy(readBuffer, 0, bmpData.Scan0, readBuffer.Length);
bmp.UnlockBits(bmpData);
How can I properly convert to a bitmap where the bottom part has not disappeared?
This is the code I used to convert the bitmap to byte.
Bitmap bmp = new Bitmap(panel1.Width, panel1.Height);
panel1.DrawToBitmap(bmp, new Rectangle(0, 0, panel1.Width, panel1.Height));
using (var stream = new MemoryStream())
{
bmp.Save(stream, ImageFormat.Png);
sendBuffer = stream.ToArray();
}
Array.Resize(ref sendBuffer, 1024*4);
The ImageHandler class is responsible for converting the image to jpg and 60x60 size, then it converts it to Base64. The first Image is fine but when I try to proccess another image in the same run it crashes.
class ImageHandler
{
public static void convertToFormat(string filename)
{
var image = Image.FromFile(#filename);
var bitmap = ResizeImage(image, Globals.ImageSize, Globals.ImageSize);
bitmap.Save(Globals.PRED_PATH, ImageFormat.Jpeg);
}
public static Bitmap ResizeImage(Image image, int width, int height)
{
var destRect = new Rectangle(0, 0, width, height);
var destImage = new Bitmap(width, height);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
public static string ConvertImageToBase64String()
{
Image image = Image.FromFile(Globals.PRED_PATH);
var imageStream = new MemoryStream();
image.Save(imageStream, ImageFormat.Jpeg);
imageStream.Position = 0;
var imageBytes = imageStream.ToArray();
return Convert.ToBase64String(imageBytes);
}
}
Function Call:
ImageHandler.convertToFormat(FilePath);
string encodedImage = ImageHandler.ConvertImageToBase64String();
As a quick fix you can add image.Dispose(); after image.Save(imageStream, ImageFormat.Jpeg); in the method ConvertImageToBase64String to make it work.
However I would recommend that you add using statements to convertToFormat and ConvertImageToBase64String to properly free the resources after use.
public static void convertToFormat(string filename)
{
using (var image = Image.FromFile(#filename))
{
using (var bitmap = ResizeImage(image, Globals.ImageSize, Globals.ImageSize))
{
bitmap.Save(Globals.PRED_PATH, ImageFormat.Jpeg);
}
}
}
public static string ConvertImageToBase64String()
{
using (var image = Image.FromFile(Globals.PRED_PATH))
{
using (var imageStream = new MemoryStream())
{
image.Save(imageStream, ImageFormat.Jpeg);
imageStream.Position = 0;
var imageBytes = imageStream.ToArray();
return Convert.ToBase64String(imageBytes);
}
}
}
EDIT: Add method where error actually occurs...
I am opening an image and I want to be able to overwrite the original file as modification happens. I tryed both of the methods here
public ImgPro(String Path)
{
Bitmap bt1 = new Bitmap(Path);
Bitmap bt2 = new Bitmap(bt1.Width, bt1.Height, PixelFormat.Format24bppRgb);
var imgRec = new Rectangle(0, 0, bt1.Width, bt1.Height);
Graphics bt2G = Graphics.FromImage(bt2);
bt2G.DrawImage(bt1, imgRec);
bt1.Dispose();
this.bitmap = bt2;
}
And
public ImgPro(String Path)
{
Bitmap bt1 = new Bitmap(Path);
Bitmap bt2 = new Bitmap(bt1.Width, bt1.Height, PixelFormat.Format24bppRgb);
var imgRec = new Rectangle(0, 0, bt1.Width, bt1.Height);
BitmapData bt1Data = bt1.LockBits(imgRec, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
BitmapData bt2Data = bt2.LockBits(imgRec, ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
// Create data array to hold bmpSource pixel data
int numBytes = bt1Data.Stride * (int)bt1.Height;
var srcData = new byte[numBytes];
var destData = new byte[numBytes];
Marshal.Copy(bt1Data.Scan0, srcData, 0, numBytes);
Array.Copy(srcData, destData, srcData.Length);
Marshal.Copy(destData, 0, bt2Data.Scan0, numBytes);
bt1.UnlockBits(bt1Data); bt2.UnlockBits(bt2Data);
bt1.Dispose();
this.bitmap = bt2;
}
But both options failed when I went to save the file I got this error.
An unhandled exception of type 'System.Runtime.InteropServices.ExternalException' occurred in System.Drawing.dll
For this method:
public void Save(string filename)
{
bitmap.Save(filename, ImageFormat.Jpeg);
}
Since Bitmap locks the underlying stream, you could copy the file contents to a MemoryStream and base the Bitmap on that instead. This should prevent the file from being locked:
var bytes = File.ReadAllBytes(Path);
using (var stream = new MemoryStream(bytes)) // Don't dispose this until you're done with your Bitmap
{
Bitmap bt1 = new Bitmap(stream);
// ...
}
I am converting bytes into an image but I get an error
Parameter is not valid
I am pasting my code. Kindly check the code and suggested that was I am doing right or wrong.
Image arr1 = byteArrayToImage(Bytess);
This is the function.
public static Image byteArrayToImage(byte[] byteArrayIn)
{
if (null == byteArrayIn || byteArrayIn.Length == 0)
return null;
MemoryStream ms = new MemoryStream(byteArrayIn);
try
{
Process currentProcess1 = Process.GetCurrentProcess();
Image returnImage = Image.FromStream(ms);
return returnImage;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I applied many techniques and solutions but it did not work for me
Your answer would be appreciated.
Thanks
try this
public Image byteArrayToImage(byte[] byteArrayIn)
{
System.Drawing.ImageConverter converter = new System.Drawing.ImageConverter();
Image img = (Image)converter.ConvertFrom(byteArrayIn);
return img;
}
After trying many things I found a way which has a little bit more control.
In this example you can specify the pixel format and copy the bytes to a Bitmap.
byte[] buffer = GetImageBytes();
var bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
var bitmap_data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(buffer, 0, bitmap_data.Scan0, buffer.Length);
bitmap.UnlockBits(bitmap_data);
var result = bitmap as Image;
The problem is because, you are bringing it incorrectly from database. Try changing your code like this:
while (registry.Read())
{
byte[] image = (byte[])registry["Image"];
}
In my case I got the error since my base64 string had wrong encoding before calling Image.FromStream.
This worked for me in the end:
byte[] bytes = System.Convert.FromBase64String(base64ImageString);
using (MemoryStream ms = new MemoryStream(bytes))
{
var image = Image.FromStream(ms);
image.Save(filePath, System.Drawing.Imaging.ImageFormat.Png);
}
cmd.CommandText="SELECT * FROM `form_backimg` WHERE ACTIVE=1";
MySqlDataReader reader6= cmd.ExecuteReader();
if(reader6.Read())
{
code4 = (byte[])reader6["BACK_IMG"]; //BLOB FIELD NAME BACK_IMG
}
reader6.Close();
MemoryStream stream = new MemoryStream(code4); //code4 is a public byte[] defined on top
pictureBox3.Image = Image.FromStream(stream);
try this,
public Image byteArrayToImage(byte[] byteArrayIn)
{
Image returnImage = null;
using (MemoryStream ms = new MemoryStream(byteArrayIn))
{
returnImage = Image.FromStream(ms);
}
return returnImage;
}
I'm trying to stream Kinect video data (just the image, not depth/infared) but I find the default buffer size on the image is very large (1228800) and incapable of sending over a network. I was wondering if there was any way of getting access to a smaller array without having to go down the route of codec compression. Here's is how I declare the Kinect which I took from a Microsoft sample;
// Turn on the color stream to receive color frames
this.sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
// Allocate space to put the pixels we'll receive
this.colorPixels = new byte[this.sensor.ColorStream.FramePixelDataLength];
// This is the bitmap we'll display on-screen
this.colorBitmap = new WriteableBitmap(this.sensor.ColorStream.FrameWidth,
this.sensor.ColorStream.FrameHeight, 96.0, 96.0, PixelFormats.Bgr32, null);
// Set the image we display to point to the bitmap where we'll put the image data
this.kinectVideo.Source = this.colorBitmap;
// Add an event handler to be called whenever there is new color frame data
this.sensor.ColorFrameReady += this.SensorColorFrameReady;
// Start the sensor!
this.sensor.Start();
And here is the New Frame event which I then try to send each frame;
private void SensorColorFrameReady(object sender,
ColorImageFrameReadyEventArgs e)
{
using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
{
if (colorFrame != null)
{
// Copy the pixel data from the image to a temporary array
colorFrame.CopyPixelDataTo(this.colorPixels);
// Write the pixel data into our bitmap
this.colorBitmap.WritePixels(
new Int32Rect(0, 0, this.colorBitmap.PixelWidth,
this.colorBitmap.PixelHeight),
this.colorPixels,
this.colorBitmap.PixelWidth * sizeof(int),
0);
if (NetworkStreamEnabled)
{
networkStream.Write(this.colorPixels, 0,
this.colorPixels.GetLength(0));
}
}
}
}
UPDATE
I'm using the following two methods to convert the ImageFrame to a Bitmap and then the Bitmap to a Byte[]. This has brought the buffer size down to ~730600. Still not enough but progress. (Source: Convert Kinect ColorImageFrame to Bitmap)
public static byte[] ImageToByte(Image img)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
Bitmap ImageToBitmap(ColorImageFrame Image)
{
byte[] pixeldata = new byte[Image.PixelDataLength];
Image.CopyPixelDataTo(pixeldata);
Bitmap bmap = new Bitmap(Image.Width, Image.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
BitmapData bmapdata = bmap.LockBits(
new Rectangle(0, 0, Image.Width, Image.Height),
ImageLockMode.WriteOnly,
bmap.PixelFormat);
IntPtr ptr = bmapdata.Scan0;
Marshal.Copy(pixeldata, 0, ptr, Image.PixelDataLength);
bmap.UnlockBits(bmapdata);
return bmap;
}
My recommendation would be to store the colorframe in a bitmap, then send those files over the network and reassemble them in a video program. A project I've been doing with the Kinect does this:
//Save to file
if (skeletonFrame != null)
{
RenderTargetBitmap bmp = new RenderTargetBitmap(800, 600, 96, 96, PixelFormats.Pbgra32);
bmp.Render(window.image);
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
// create frame from the writable bitmap and add to encoder
if (skeletonFrame.Timestamp - lastTime > 90)
{
encoder.Frames.Add(BitmapFrame.Create(bmp));
string myPhotos = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
string path = "C:your\\directory\\here" + skeletonFrame.Timestamp + ".jpg";
using (FileStream fs = new FileStream(path, FileMode.Create))
{
encoder.Save(fs);
}
lastTime = skeletonFrame.Timestamp;
}
}
Of course, if you need this to be in real time, you're not going to like this solution, and I think my "comment" button is gone after the bounty.