I am trying to send images from wcf ksoap2 to android.
At wcf side I have converted all images into byte array and stored them in an ArrayList.
At android side I fill the ArrayList from wcf response.
Now the problem is byte array is not receiving properly and byte array is not converting into Image/BufferedImage.
Here is my code
byt = new byte[4096];
byt = (byte[]) al.get(5);
//Image im;
BufferedImage bImageFromConvert = null;
InputStream in = new ByteArrayInputStream(byt);
try {
bImageFromConvert = ImageIO.read(in);
//ImageIO.write(bImageFromConvert, "jpg", new File(
// "c:/new-darksouls.jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
al is my ArrayList.
private String prepareImage() {
if (tempPath == null ) {
return "";
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(tempPath, options);
bitmap = Bitmap.createScaledBitmap(bitmap, 50, 50, true);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//bitmap.compress(Bitmap.CompressFormat.PNG, 50, baos);
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos);
byte[] byteArray = baos.toByteArray();
String imageString = com.size4u.utils.Base64
.encodeBytes(byteArray);
bitmap = null;
System.gc();
Runtime.getRuntime().gc();
return imageString;
}
Related
I know this has been asked numerous times... and I have searched and tried everything that I can, but I am still not sure why I get the "parameter is not valid" exception...
I have an Amazon EC2 instance running Windows Server 2012. On that machine, I am running Unity3D (Unity 5). That Unity application is sending frames (images) from the EC2 instance to my local laptop, via TCP. My client is running Windows 10, not that it is likely to make any difference.
To get my image data, I do the following:
byte[] GetScreenData() {
// Create a texture the size of the screen, RGB24 format
int width = Screen.width;
int height = Screen.height;
RenderTexture rt = new RenderTexture(width, height, 24);
Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false);
Camera camera = GameObject.Find("Main Camera").GetComponent < Camera > ();
camera.targetTexture = rt;
camera.Render();
RenderTexture.active = rt;
// Read screen contents into the texture
tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
camera.targetTexture = null;
RenderTexture.active = null;
Destroy(rt);
// Encode texture into JPG
byte[] bytes = tex.EncodeToJPG();
Destroy(tex);
return bytes;
}
I then serialize my data using FlatBuffers:
public static byte[] FlatSerialize(this ServerToClientMessage message) {
var builder = new FlatBufferBuilder(1);
//Create an ID
var MessageId = builder.CreateString(message.MessageId.ToString());
//Start the vector...
//Loop over each byte and add it - my god, is there not a better way?
FlatServerToClientMessage.StartImagebytesVector(builder, message.ImageBytes.Length);
foreach(var imageByte in message.ImageBytes) {
builder.AddByte(imageByte);
}
var imagebytes = builder.EndVector();
//Start the FlatServerToClientMessage and add the MessageId and imagebytes
FlatServerToClientMessage.StartFlatServerToClientMessage(builder);
FlatServerToClientMessage.AddMessageid(builder, MessageId);
FlatServerToClientMessage.AddImagebytes(builder, imagebytes);
//End the FlatServerToClientMessage and finish it...
var flatMessage = FlatServerToClientMessage.EndFlatServerToClientMessage(builder);
FlatServerToClientMessage.FinishFlatServerToClientMessageBuffer(builder, flatMessage);
return builder.SizedByteArray();
}
Next, I send my data:
public void SendRaw(byte[] dataToSend) {
///We must send the length of the message before sending the actual message
var sizeInfo = new byte[4]; // = BitConverter.GetBytes(dataToSend.Length);
//Shift the bytes
sizeInfo[0] = (byte) dataToSend.Length;
sizeInfo[1] = (byte)(dataToSend.Length >> 8);
sizeInfo[2] = (byte)(dataToSend.Length >> 16);
sizeInfo[3] = (byte)(dataToSend.Length >> 24);
try {
var stream = Client.GetStream();
//Send the length of the data
stream.Write(sizeInfo, 0, 4);
//Send the data
stream.Write(dataToSend, 0, dataToSend.Length);
} catch (Exception ex) {
Debug.LogException(ex);
} finally {
//raise event to tell system that the client has disconnected and that listening must restart...
}
}
Back on my client device, I am listening for incoming data which deserializes and raises an event to alert the system to the arrival of a new image...
private void Run() {
try {
// ShutdownEvent is a ManualResetEvent signaled by
// Client when its time to close the socket.
while (!ShutDownEvent.WaitOne(0)) {
try {
if (!_stream.DataAvailable) continue;
//Read the first 4 bytes which represent the size of the message, and convert from byte array to int32
var sizeinfo = new byte[4];
_stream.Read(sizeinfo, 0, 4);
var messageSize = BitConverter.ToInt32(sizeinfo, 0);
//create a new buffer for the data to be read
var buffer = new byte[messageSize];
var read = 0;
//Continue reading from the stream until we have read all bytes #messageSize
while (read != messageSize) {
read += _stream.Read(buffer, read, buffer.Length - read);
}
var message = new ServerToClientMessage().FlatDeserialize(buffer);
//raise data received event
OnDataReceived(message);
} catch (IOException ex) {
// Handle the exception...
}
}
} catch (Exception ex) {
// Handle the exception...
} finally {
_stream.Close();
}
}
To deserialize, I do the following:
public static ServerToClientMessage FlatDeserialize(this ServerToClientMessage message, byte[] bytes) {
var bb = new ByteBuffer(bytes);
var flatmessage = FlatServerToClientMessage.GetRootAsFlatServerToClientMessage(bb);
message.MessageId = new Guid(flatmessage.Messageid);
message.ImageBytes = new byte[flatmessage.ImagebytesLength];
for (var i = 0; i < flatmessage.ImagebytesLength; i++) {
message.ImageBytes[i] = flatmessage.GetImagebytes(i);
}
return message;
}
For clarity, here is the ServerToClientMessage class:
public class ServerToClientMessage : EventArgs
{
public Guid MessageId { get; set; }
public byte[] ImageBytes { get; set; }
}
Anyway, next, the OnDataReceived event gets raised and that in turn calls a function to convert from the ImageBytes array to a System.Drawing.Image. That function is here:
public Image byteArrayToImage(byte[] byteArrayIn) {
// SAME PROBLEM!
//var converter = new System.Drawing.ImageConverter();
// return (Image)converter.ConvertFrom(byteArrayIn); ;
using(var memoryStream = new MemoryStream(byteArrayIn)) {
return Image.FromStream(memoryStream, false, false);
}
}
Now, my image data being sent from the server is fine and dandy... I have validated it. This all works fine when I use JSON, too. I've tried many ways to convert from a byte array to an Image, but I always seem to get the Parameter is not valid exception. I've also tried sending my image in different formats like JPG and PNG, as well as raw pixel data.
Anyone have an idea?
Figured it out.
It turns out that the data is backwards...due to FlatBuffers serialization.
The solution is to reverse the order of my for-loop during serialization:
for (var i = message.ImageBytes.Length; i -->0;)
{
builder.AddByte(message.ImageBytes[i]);
}
Hi am trying to get bitmap to display from DICOM file , but when try to create bitmap from the buffer I get Parameter is not valid for the Bitmap constructor call. I use the following code
gdcm.ImageReader reader = new gdcm.ImageReader();
reader.SetFileName(_dicomFilePath);
if (reader.Read())
{
var image = reader.GetImage();
if (image != null)
{
byte[] imageByteArray = new byte[image.GetBufferLength()];
if (image.GetBuffer(imageByteArray))
{
MemoryStream stream = new MemoryStream();
stream.Write(imageByteArray, 0, imageByteArray.Length);
stream.Seek(0, SeekOrigin.Begin);
Bitmap bmp = new Bitmap(stream);
CurrentFrameDataGDCM = Imaging.CreateBitmapSourceFromHBitmap(
bmp.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromWidthAndHeight((int)image.GetRows(), (int)image.GetColumns()));
}
}
}
I have 2 Apps (server - client ) .
The server is modified version of TVsharp (Application that stream local analog tv signal using RTLSDR)
Each frame of the streamed video is a grayscale array of bytes .
I have modified it so it re sizes and sends each frame for a client over TCP socket
The client is supposed to receive the frames through the socket as Image objects and displays them in a picture box
Im getting invalid parameters error .
After i added a delay (Thread.Sleep()) it started to display one frame and then it gives invalid parameter exception (after the sleeping time)
This is the part of TVsharp that dose the sending :
Grayscale is an array that contains the brightness for each pixel
private string drive = "E:\\";
private string file = "0";
private string extension = ".bmp";
private string path2 = "E:\\test\\";
private string fullpath;
private int file_counter = 0;
Bitmap bitmap2 = new Bitmap(_pictureWidth, _pictureHeight);
var data2 = bitmap2.LockBits(new Rectangle(Point.Empty, bitmap2.Size),
ImageLockMode.WriteOnly,PixelFormat.Format24bppRgb);
Marshal.Copy(GrayScaleValues, 0, data2.Scan0, GrayScaleValues.Length);
bitmap2.UnlockBits(data2);
bitmap2.Save(fullpath, System.Drawing.Imaging.ImageFormat.Bmp);
string Npath = path2 + file + extension;
Image img = Image.FromFile(fullpath);
// Size size = new Size(982, 543);
// ResizeImage(img, size);
Rectangle cropRect = new Rectangle(80, 0, 240, 175);
Bitmap target = new Bitmap(cropRect.Width, cropRect.Height);
using (Graphics g = Graphics.FromImage(target))
{
g.DrawImage(img, new Rectangle(0, 0, target.Width, target.Height), cropRect, GraphicsUnit.Pixel);
}
//double scale = 203 / 96;
int width = (int)(target.Width);
int height = (int)(target.Height);
BinaryWriter brn = new BinaryWriter(s);
System.Drawing.Bitmap bmpScaled = new System.Drawing.Bitmap(target, width, height);
bmpScaled.Save(Npath);
byte[] imageArray = File.ReadAllBytes(Npath);
sw.WriteLine(imageArray.Length.ToString());
sw.Flush();
// Thread.Sleep(500);
brn.Write(imageArray);
//Thread.Sleep(500);
_detectLevel = Convert.ToInt32(_maxSignalLevel * _detectorLevelCoef);
_agcSignalLevel = agcMaxLevel;
}
This client the client segment that suppose to get the frames and display them
flag = true;
TcpClient client = new TcpClient(textBox1.Text, Convert.ToInt32(textBox2.Text));
Stream s = client.GetStream();
StreamReader sr = new StreamReader(s);
StreamWriter sw = new StreamWriter(s);
sw.Flush();
BinaryFormatter formatter = new BinaryFormatter();
string msg = sr.ReadLine();
MessageBox.Show("It's working !! the message is " + msg);
BinaryReader Brn = new BinaryReader(s);
Thread.Sleep(5000);
while (flag)
{
// Thread.Sleep(5000);
int size = Convert.ToInt32(sr.ReadLine());
label3.Text = "Size is " + size;
byte[] imagerray = Brn.ReadBytes(size);
MemoryStream ms = new MemoryStream(imagerray);
Thread.Sleep(10000);
Image image = Image.FromStream(ms);
ResizeImage(image, this.Size);
pictureBox1.Image = image;
Thread.Sleep(10);
}
}
I am trying to develop an application for Windows Phone 7 which uploads a selected picture (from the picture chooser task) to a server with the use of PHP.
I am trying to use HttpWebRequest in order to do this. And the data is posted successfully too.
The Problem that I am facing is that the image is required to be encoded to base64 before posting.
And, I am not able to encode it properly.
This is my C# code so far:
public partial class SamplePage : PhoneApplicationPage
{
public SamplePage()
{
InitializeComponent();
}
PhotoChooserTask selectphoto = null;
private void SampleBtn_Click(object sender, RoutedEventArgs e)
{
selectphoto = new PhotoChooserTask();
selectphoto.Completed += new EventHandler<PhotoResult>(selectphoto_Completed);
selectphoto.Show();
}
void selectphoto_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
BinaryReader reader = new BinaryReader(e.ChosenPhoto);
image1.Source = new BitmapImage(new Uri(e.OriginalFileName));
txtBX.Text = e.OriginalFileName;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://"+QR_Reader.MainPage.txtBlck+"/beamer/saveimage.php");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string str = BitmapToByte(image1);
MessageBox.Show(str);
string postData = String.Format("image={0}", str);
// Getting the request stream.
request.BeginGetRequestStream
(result =>
{
// Sending the request.
using (var requestStream = request.EndGetRequestStream(result))
{
using (StreamWriter writer = new StreamWriter(requestStream))
{
writer.Write(postData);
writer.Flush();
}
}
// Getting the response.
request.BeginGetResponse(responseResult =>
{
var webResponse = request.EndGetResponse(responseResult);
using (var responseStream = webResponse.GetResponseStream())
{
using (var streamReader = new StreamReader(responseStream))
{
string srresult = streamReader.ReadToEnd();
}
}
}, null);
}, null);
} // end of taskresult == OK
} // end of select photo completed
private Stream ImageToStream(Image image1)
{
WriteableBitmap wb = new WriteableBitmap(400, 400);
wb.Render(image1, new TranslateTransform { X = 400, Y = 400 });
wb.Invalidate();
Stream myStream = new MemoryStream();
wb.SaveJpeg(myStream, 400, 400, 0, 70);
return myStream;
}
private string BitmapToByte(Image image) //I suspect there is something wrong here
{
Stream photoStream = ImageToStream(image);
BitmapImage bimg = new BitmapImage();
bimg.SetSource(photoStream); //photoStream is a stream containing data for a photo
byte[] bytearray = null;
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap wbitmp = new WriteableBitmap(bimg);
wbitmp.SaveJpeg(ms, wbitmp.PixelWidth, wbitmp.PixelHeight, 0, 100);
bytearray = ms.ToArray();
}
string str = Convert.ToBase64String(bytearray);
return str;
}
}
The BitmapToByte function is used to convert the image to base64 string.
And, the ImageToStream function is used to convert it to stream.
Now, I seriously suspect that there is something wrong in these two functions.
Further, I'm getting exactly the same base64 string for every image. Yes, I'm getting exactly same base64 string irrespective of what image I'm selecting. This is very weird.
I don't know what is wrong with this.
I've uploaded a text file here: http://textuploader.com/?p=6&id=vWZy
It contains that base64 string.
On, the server side, the PHP is accepting the postdata successfully and the decoding is working perfectly too (I decoded some base64 strings manually to ensure this).
Only problem I'm facing is base64 encoding.
Please help me.
EDIT
I've made the following changes in the ImageToStream and BitmapToByte functions:
private MemoryStream ImageToStream(Image image1)
{
WriteableBitmap wb = new WriteableBitmap(400, 400);
wb.Render(image1, new TranslateTransform { X = 400, Y = 400 });
wb.Invalidate();
MemoryStream myStream = new MemoryStream();
wb.SaveJpeg(myStream, 400, 400, 0, 70);
return myStream;
}
private string BitmapToByte(Image image)
{
MemoryStream photoStream = ImageToStream(image);
byte[] bytearray = photoStream.ToArray();
string str = Convert.ToBase64String(bytearray);
return str;
}
You BitmapToByte method is tremendously overcomplicated. Change ImageToStream to return a MemoryStream and:
private string BitmapToByte(Image image)
{
MemoryStream photoStream = ImageToStream(image);
byte[] bytearray = photoStream.ToArray();
string str = Convert.ToBase64String(bytearray);
return str;
}
Could anyone tell me how I could retrieve an image or a thumbnail of a website through my ASP.NET application? I have seen this functionality in a few sites such as Alexa etc.
Try SnapCasa's free and easy to use service. Just form your image tag like this:
<img src="http://SnapCasa.com/Get.aspx?code=[code]&size=[size]&url=[url]" />
Requires sign-up, but it's free for 500,000 requests a month. [code] is an api key that they provide after sign-up. [size] is one of three sizes available. [url] is the website address to the site for which you want to display a thumbnail.
If you want to work with the image from your code, here are a couple of helper methods:
static public byte[] GetBytesFromUrl(string url)
{
byte[] b;
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
WebResponse myResp = myReq.GetResponse();
Stream stream = myResp.GetResponseStream();
//int i;
using (BinaryReader br = new BinaryReader(stream))
{
//i = (int)(stream.Length);
b = br.ReadBytes(500000);
br.Close();
}
myResp.Close();
return b;
}
static public void WriteBytesToFile(string fileName, byte[] content)
{
FileStream fs = new FileStream(fileName, FileMode.Create);
BinaryWriter w = new BinaryWriter(fs);
try
{
w.Write(content);
}
finally
{
fs.Close();
w.Close();
}
}
Then, in your code, just use:
//get byte array for image
var imageBytes = GetBytesFromUrl("http://SnapCasa.com/Get.aspx?code=[code]&size=[size]&url=[url]");
//save file to disk
WriteBytesToFile("c:\someImageFile.jpg", imageBytes);
Should be doable using a web-browser object and saving the view port to a bitmap resized to thumbnail.
I have not tested this code but try tweaking it after substituting for the thumbnail params.
using (WebBrowser wb = new WebBrowser()) {
wb.ScrollBarsEnabled = false;
wb.AllowNavigation = true;
wb.ScriptErrorsSuppressed = true;
wb.ClientSize = new Size(thumbInfo_viewportWidth, thumbInfo_viewportHeight);
if ((thumbInfo_Uri != null)) {
wb.Navigate(thumbInfo_Uri.AbsoluteUri);
} else {
wb.Navigate("about:blank");
HtmlDocument doc = wb.Document.OpenNew(true);
doc.Write(thumbInfo_HTML);
wb.Refresh(WebBrowserRefreshOption.Completely);
}
// create an image of the client area of the webbrowser control, than
// scale it down to the dimensions specified.
if ((wb.Document != null && wb.Document.Body != null)) {
Rectangle rec = default(Rectangle);
rec.Size = wb.ClientSize;
using (Bitmap fullSizeBitmap = new Bitmap(thumbInfo_viewportWidth, thumbInfo_viewportHeight)) {
wb.DrawToBitmap(fullSizeBitmap, wb.Bounds);
using (Bitmap scaledBitmap = new Bitmap(thumbInfo_width, thumbInfo_height)) {
using (Graphics gr = Graphics.FromImage(scaledBitmap)) {
gr.SmoothingMode = Drawing2D.SmoothingMode.HighQuality;
gr.CompositingQuality = Drawing2D.CompositingQuality.HighQuality;
gr.InterpolationMode = Drawing2D.InterpolationMode.High;
Rectangle rect = new Rectangle(0, 0, thumbInfo_width, thumbInfo_height);
gr.DrawImage(fullSizeBitmap, rect, 0, 0, rec.Size.Width, rec.Size.Height, GraphicsUnit.Pixel);
scaledBitmap.Save(thumbInfo_physicalPath);
}
}
}
}
}
One thing to note that it is an expensive process.