I want to make a bitmap and save it and display it. I can display it but I cannot save it.
I get this runtime error : System.Runtime.InteropServices.ExternalException: 'A generic error occurred in GDI+.'
I am even using using and I still get that error
private void button1_Click(object sender, EventArgs e)
{
byte[] returndata = new byte[7057600];
for (int x = 0; x < returndata.Length; )
{
returndata[x] = 255;
returndata[x + 1] = 255;
returndata[x + 2] = 0;
returndata[x + 3] = 0;
x = x + 4;
}
using (SaveFileDialog saveFileDialog1 = new SaveFileDialog())
{
saveFileDialog1.Filter = "Bitmaps|*.bmp";
Bitmap temp = null;
temp = InttoBitmap(returndata);
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
string location = saveFileDialog1.FileName;
temp.Save(location, ImageFormat.Bmp);
pictureBox1.Image = temp;
}
}
}
int keepWidth = 3208;
int keepHeight = 2200;
public Bitmap InttoBitmap(byte[] array)
{
unsafe
{
IntPtr pixptr = Marshal.AllocHGlobal(keepWidth * keepHeight * 4);
Marshal.Copy(array, 0, pixptr, keepWidth * keepHeight);
Bitmap bitmap = new Bitmap(keepWidth, keepHeight, 2 * keepWidth, System.Drawing.Imaging.PixelFormat.Format24bppRgb, pixptr);
return bitmap;
}
}
Related
I am trying to use the save file dialog in a windows forms project of mine. When trying to save a file I use the showDialog() method and it throws a System.AccessViolationError. The initial directory of the save file dialog isn't set so I don't see why there is an access violation. Here's the code I wrote for using the save file dialog:
var imageSaver = new SaveFileDialog();
imageSaver.Filter = fileType + " File|*." + fileType;
imageSaver.Title = "Save Image";
if (imageSaver.ShowDialog() == DialogResult.OK)
{
b.Save(imageSaver.FileName, imgFormat);
Close();
}
This block of code is used in an event for when a button is clicked, however, after a bit of testing, I found out that the same code works when used in the constructor of the form and in the load event of the form.
Here is the entire class:
using System.Drawing.Imaging;
namespace Pixart
{
public partial class ImageGenerator : Form
{
int width;
int height;
Cell[,] cells;
ImageFormat imgFormat;
string fileType;
bool useMultiplier;
public ImageGenerator(string fileType, ImageFormat imgFormat, Cell[,] cells, int width, int height)
{
InitializeComponent();
this.width = width;
this.height = height;
this.cells = cells;
this.imgFormat = imgFormat;
this.fileType = fileType;
titleLabel.Text = "Export " + fileType.ToUpper();
widthNumber.Minimum = width;
widthNumber.Increment = width;
widthNumber.Maximum = (4000 / width) * width;
heightNumber.Minimum = height;
heightNumber.Increment = height;
heightNumber.Maximum = (4000 / height) * height;
if (heightNumber.Maximum / height < widthNumber.Maximum / width)
multiplierNumber.Maximum = heightNumber.Maximum / height;
else
multiplierNumber.Maximum = widthNumber.Maximum / width;
widthLabel.ForeColor = SystemColors.ControlDarkDark;
heightLabel.ForeColor = SystemColors.ControlDarkDark;
sizeLabel.ForeColor = SystemColors.ControlDarkDark;
multiplierLabel.ForeColor = SystemColors.ControlText;
useMultiplier = true;
//The code works here for some reason
//var imageSaver = new SaveFileDialog();
//imageSaver.Filter = fileType + " File|*." + fileType;
//imageSaver.Title = "Save Image";
//if (imageSaver.ShowDialog() == DialogResult.OK)
//{
//}
}
private void ImageGenerator_Load(object sender, EventArgs e)
{
//The code also works here
//var imageSaver = new SaveFileDialog();
//imageSaver.Filter = fileType + " File|*." + fileType;
//imageSaver.Title = "Save Image";
//if (imageSaver.ShowDialog() == DialogResult.OK)
//{
//}
}
private void multiplierNumber_ValueChanged(object sender, EventArgs e)
{
widthLabel.ForeColor = SystemColors.ControlDarkDark;
heightLabel.ForeColor = SystemColors.ControlDarkDark;
sizeLabel.ForeColor = SystemColors.ControlDarkDark;
multiplierLabel.ForeColor = SystemColors.ControlText;
useMultiplier = true;
}
private void widthNumber_ValueChanged(object sender, EventArgs e)
{
widthLabel.ForeColor = SystemColors.ControlText;
heightLabel.ForeColor = SystemColors.ControlText;
multiplierLabel.ForeColor = SystemColors.ControlDarkDark;
sizeLabel.ForeColor = SystemColors.ControlText;
useMultiplier = false;
widthNumber.Value = (widthNumber.Value / width) * width;
}
private void heightNumber_ValueChanged(object sender, EventArgs e)
{
widthLabel.ForeColor = SystemColors.ControlText;
heightLabel.ForeColor = SystemColors.ControlText;
multiplierLabel.ForeColor = SystemColors.ControlDarkDark;
sizeLabel.ForeColor = SystemColors.ControlText;
useMultiplier = false;
heightNumber.Value = (Convert.ToInt32(heightNumber.Value) / height) * height;
}
private void saveButton_Click(object sender, EventArgs e)
{
int imageWidth = width * Convert.ToInt32(multiplierNumber.Value);
int imageHeight = height * Convert.ToInt32(multiplierNumber.Value);
if (!useMultiplier)
{
imageWidth = Convert.ToInt32(widthNumber.Value);
imageHeight = Convert.ToInt32(heightNumber.Value);
}
using (Bitmap b = new Bitmap(imageWidth, imageHeight))
{
for (int r = 0; r < height; r++)
{
for (int c = 0; c < width; c++)
{
for (int y = 0; y < imageHeight / height; y++)
{
for (int x = 0; x < imageWidth / width; x++)
{
b.SetPixel((c * (imageWidth / width)) + x, (r * (imageHeight / height)) + y, cells[c, r].Colour);
}
}
}
}
var imageSaver = new SaveFileDialog();
imageSaver.Filter = fileType + " File|*." + fileType;
imageSaver.Title = "Save Image";
//line after this throws an error
if (imageSaver.ShowDialog() == DialogResult.OK)
{
b.Save(imageSaver.FileName, imgFormat);
Close();
}
}
}
private void cancelButton_Click(object sender, EventArgs e)
{
Close();
}
private void ImageGenerator_Deactivate(object sender, EventArgs e)
{
Close();
}
}
}
The error message System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory in your code is occurring because the Form Deactivate event occurs when the SaveFileDialog opens.
The issue is due to the following code:
private void ImageGenerator_Deactivate(object sender, EventArgs e)
{
Close();
}
Solution: Remove Close() (or comment it out)
private void ImageGenerator_Deactivate(object sender, EventArgs e)
{
}
I have just started learning kinect, and I tried following one of the examples online, but I am returned this error:
No overload for 'msfr_MultiSourceFrameArrived matches delegate 'TypedEventHandler'
I pointed out where the error line is at in the code, which is above the sensor.Open in MainPage
How my code looks like :
KinectSensor sensor;
InfraredFrameReader irReader;
ushort[] irData;
byte[] irDataConverted;
WriteableBitmap irBitmap;
Body[] bodies;
MultiSourceFrameReader msfr;
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
sensor = KinectSensor.GetDefault();
irReader = sensor.InfraredFrameSource.OpenReader();
FrameDescription fd = sensor.InfraredFrameSource.FrameDescription;
irData = new ushort[fd.LengthInPixels];
irDataConverted = new byte[fd.LengthInPixels * 4];
irBitmap = new WriteableBitmap(fd.Width, fd.Height);
image.Source = irBitmap;
bodies = new Body[6];
msfr = sensor.OpenMultiSourceFrameReader(FrameSourceTypes.Body| FrameSourceTypes.Infrared);
msfr.MultiSourceFrameArrived += msfr_MultiSourceFrameArrived; <-- the error
sensor.Open();
}
void msfr_MultiSourceFrameArrived(MultiSourceFrameReader sender, MultiSourceFrame args)
{
using (MultiSourceFrame msf = args.BodyFrameReference.AcquireFrame())
{
if (msf != null)
{
using (BodyFrame bodyFrame = msf.BodyFrameReference.AcquireFrame())
{
using (InfraredFrame irFrame = msf.InfraredFrameReference.AcquireFrame())
{
if (bodyFrame != null && irFrame != null)
{
irFrame.CopyFrameDataToArray(irData);
for (int i = 0; i < irData.Length; i++)
{
byte intensity = (byte)(irData[i] >> 8);
irDataConverted[i * 4] = intensity;
irDataConverted[i * 4 + 1] = intensity;
irDataConverted[i * 4 + 2] = intensity;
irDataConverted[i * 4 + 3] = 255;
}
irDataConverted.CopyTo(irBitmap.PixelBuffer);
irBitmap.Invalidate();
bodyFrame.GetAndRefreshBodyData(bodies);
bodyCanvas.Children.Clear();
foreach (Body body in bodies)
{
if (body.IsTracked)
{
Joint headJoint = body.Joints[JointType.Head];
if (headJoint.TrackingState == TrackingState.Tracked)
{
DepthSpacePoint dsp = sensor.CoordinateMapper.MapCameraPointsToDepthSpace(headJoint.Position);
Ellipse headCircle = new Ellipse() { Width = 50, Height = 50, Fill = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) };
bodyCanvas.Children.Add(headCircle);
Canvas.SetLeft(headCircle, dsp.X-25);
Canvas.SetTop(headCircle, dsp.Y-25);
}
}
}
}
}
}
}
}
}
Try changing the argument in msfr_MultiSourceFrameArrived() from MultiSourceFrame args to MultiSourceFrameArrivedEventArgs args
The MultiSourceFrameArrived event of the FrameReader is expecting a specific type of eventhandler argument and it's telling you the one you currently use is not what it's expecting.
I wanted to make an application which can read data from the webcam. It makes the really bright pixels red (right now). But I can't write it out into an imagebox. So what is the problem?
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
WebCam camera = new WebCam();
if (!camera.IsConnected())
{
camera.Connect();
}
else
{
Application.Exit();
}
// for (int x = 0; x <= 10000; x++)
// {
camera.Update();
MemoryStream ms = new MemoryStream();
camera.CalcBitmap().Save(ms, ImageFormat.Bmp);
byte[] bitmapData = ms.ToArray();
/*
int i = 54;
while (i <= (bitmapData.Length - 2))
{
if ((bitmapData[i] >= 240) & (bitmapData[i + 1] >= 240) & (bitmapData[i + 2] >= 240))
{
bitmapData[i] = 255;
bitmapData[i + 1] = 0;
bitmapData[i + 2] = 0;
i += 3;
}
}*/
MemoryStream stream = new MemoryStream(bitmapData);
pictureBox1.Image = new Bitmap(stream);
// }
}
So after lot of suffering I leaved the picturebox function empty and i wrote everything into a buttonclick function. And it worked! I still don't know what was the problem, but I think the picturebox funtoin tired to connect to the webcam even if it was connected.
public partial class Form1 : Form
{
public static WebCam camera = new WebCam();
private void button1_Click(object sender, EventArgs e)
{
if (!camera.IsConnected())
{
camera.Connect();
camera.Update();
MemoryStream ms = new MemoryStream();
camera.CalcBitmap().Save(ms, ImageFormat.Bmp);
byte[] bitmapData = ms.ToArray();
MemoryStream stream = new MemoryStream(bitmapData);
pictureBox1.Image = new Bitmap(stream);
}
else
{
Application.Exit();
}
}
public void pictureBox1_Paint(object sender, PaintEventArgs e)
{
}
You must call Dispose() on objects that holds unmanaged resources so the memory can be freed.
MemoryStream ms = null
try{
//your code
}
finally{
if(ms != null){
ms.Dispose()
}
}
i want to convert a string entered by user to an image..how can it be done?
i tried the following code but i get an argument exception in the line :
WriteableBitmap wbimg = PictureDecoder.DecodeJpeg(memStream);
static public string EncodeTo64(string toEncode)
{
byte[] toEncodeAsBytes
= StringToAscii(toEncode);
string returnValue
= System.Convert.ToBase64String(toEncodeAsBytes);
return returnValue;
}
public static byte[] StringToAscii(string s)
{
byte[] retval = new byte[s.Length];
for (int ix = 0; ix < s.Length; ++ix)
{
char ch = s[ix];
if (ch <= 0x7f) retval[ix] = (byte)ch;
else retval[ix] = (byte)'?';
}
return retval;
}
void convert()
{
String s = textBox1.Text;
byte[] data = Convert.FromBase64String(EncodeTo64(s));
for (int i = 0; i < data.Length; i++)
{
System.Diagnostics.Debug.WriteLine(data[i]);
}
Stream memStream = new MemoryStream();
memStream.Write(data, 0, data.Length);
try
{
WriteableBitmap wbimg = PictureDecoder.DecodeJpeg(memStream);
image1.Source = wbimg;
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
I got what i wanted in the following links.. How can I render text on a WriteableBitmap on a background thread, in Windows Phone 7? and http://blogs.u2u.be/michael/post/2011/04/20/Adding-a-text-to-an-image-in-WP7.aspx Thanks to all those who replied for the initial help! :)
It is the simple way you can convert TextBlock Text into Image
private void convert_Click(object sender, RoutedEventArgs e)
{
Canvas c1 = new Canvas();
TextBlock t = new TextBlock();
t.Text = text1.Text;
t.FontFamily = text1.FontFamily;
t.Foreground = text1.Foreground;
t.FontSize = text1.FontSize;
c1.Children.Add(t);
WriteableBitmap wbmp = new WriteableBitmap(c1, null);
im = new Image();
im.Source = wbmp;
im.Height = 200;
im.Width = 200;
Canvas.SetTop(im, 10);
Canvas.SetLeft(im, 10);
Main_Canvas.Children.Add(im);
}
Here I convert the Textblock Text into Bitmap and then assign it to the image source.
Here is how to writte a string to a bitmap:
Bitmap b = new Bitmap(200, 100);
Graphics g = Graphics.FromImage(b);
g.DrawString("My sample string", new Font("Tahoma",10), Brushes.Red, new Point(0, 0));
b.Save("mypic.png", System.Drawing.Imaging.ImageFormat.Png);
g.Dispose();
b.Dispose();
Shubhi1910 let me know if you need any details to be explained.
I am doing OCR application. I have this error when I run the system which the system will save the picturebox3.image into a folder.
//When user is selecting, RegionSelect = true
private bool RegionSelect = false;
private int x0, x1, y0, y1;
private Bitmap bmpImage;
private void loadImageBT_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog open = new OpenFileDialog();
open.InitialDirectory = #"C:\Users\Shen\Desktop";
open.Filter = "Image Files(*.jpg; *.jpeg)|*.jpg; *.jpeg";
if (open.ShowDialog() == DialogResult.OK)
{
singleFileInfo = new FileInfo(open.FileName);
string dirName = System.IO.Path.GetDirectoryName(open.FileName);
loadTB.Text = open.FileName;
pictureBox1.Image = new Bitmap(open.FileName);
bmpImage = new Bitmap(pictureBox1.Image);
}
}
catch (Exception)
{
throw new ApplicationException("Failed loading image");
}
}
//User image selection Start Point
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
RegionSelect = true;
//Save the start point.
x0 = e.X;
y0 = e.Y;
}
//User select image progress
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
//Do nothing it we're not selecting an area.
if (!RegionSelect) return;
//Save the new point.
x1 = e.X;
y1 = e.Y;
//Make a Bitmap to display the selection rectangle.
Bitmap bm = new Bitmap(bmpImage);
//Draw the rectangle in the image.
using (Graphics g = Graphics.FromImage(bm))
{
g.DrawRectangle(Pens.Red, Math.Min(x0, x1), Math.Min(y0, y1), Math.Abs(x1 - x0), Math.Abs(y1 - y0));
}
//Temporary display the image.
pictureBox1.Image = bm;
}
//Image Selection End Point
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
// Do nothing it we're not selecting an area.
if (!RegionSelect) return;
RegionSelect = false;
//Display the original image.
pictureBox1.Image = bmpImage;
// Copy the selected part of the image.
int wid = Math.Abs(x0 - x1);
int hgt = Math.Abs(y0 - y1);
if ((wid < 1) || (hgt < 1)) return;
Bitmap area = new Bitmap(wid, hgt);
using (Graphics g = Graphics.FromImage(area))
{
Rectangle source_rectangle = new Rectangle(Math.Min(x0, x1), Math.Min(y0, y1), wid, hgt);
Rectangle dest_rectangle = new Rectangle(0, 0, wid, hgt);
g.DrawImage(bmpImage, dest_rectangle, source_rectangle, GraphicsUnit.Pixel);
}
// Display the result.
pictureBox3.Image = area;
** ERROR occuer here!!!!!**
area.Save(#"C:\Users\Shen\Desktop\LenzOCR\TempFolder\tempPic.jpg"); // error line occcur
singleFileInfo = new FileInfo("C:\\Users\\Shen\\Desktop\\LenzOCR\\TempFolder\\tempPic.jpg");
}
private void ScanBT_Click(object sender, EventArgs e)
{
var folder = #"C:\Users\Shen\Desktop\LenzOCR\LenzOCR\WindowsFormsApplication1\ImageFile";
DirectoryInfo directoryInfo;
FileInfo[] files;
directoryInfo = new DirectoryInfo(folder);
files = directoryInfo.GetFiles("*.jpg", SearchOption.AllDirectories);
var processImagesDelegate = new ProcessImagesDelegate(ProcessImages2);
processImagesDelegate.BeginInvoke(files, null, null);
//BackgroundWorker bw = new BackgroundWorker();
//bw.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
//bw.RunWorkerAsync(bw);
//bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
}
private void ProcessImages2(FileInfo[] files)
{
var comparableImages = new List<ComparableImage>();
var index = 0x0;
foreach (var file in files)
{
if (exit)
{
return;
}
var comparableImage = new ComparableImage(file);
comparableImages.Add(comparableImage);
index++;
}
index = 0;
similarityImagesSorted = new List<SimilarityImages>();
var fileImage = new ComparableImage(singleFileInfo);
for (var i = 0; i < comparableImages.Count; i++)
{
if (exit)
return;
var destination = comparableImages[i];
var similarity = fileImage.CalculateSimilarity(destination);
var sim = new SimilarityImages(fileImage, destination, similarity);
similarityImagesSorted.Add(sim);
index++;
}
similarityImagesSorted.Sort();
similarityImagesSorted.Reverse();
similarityImages = new BindingList<SimilarityImages>(similarityImagesSorted);
var buttons =
new List<Button>
{
ScanBT
};
if (similarityImages[0].Similarity > 70)
{
con = new System.Data.SqlClient.SqlConnection();
con.ConnectionString = "Data Source=SHEN-PC\\SQLEXPRESS;Initial Catalog=CharacterImage;Integrated Security=True";
con.Open();
String getFile = "SELECT ImageName, Character FROM CharacterImage WHERE ImageName='" + similarityImages[0].Destination.ToString() + "'";
SqlCommand cmd2 = new SqlCommand(getFile, con);
SqlDataReader rd2 = cmd2.ExecuteReader();
while (rd2.Read())
{
for (int i = 0; i < 1; i++)
{
string getText = rd2["Character"].ToString();
Action showText = () => ocrTB.AppendText(getText);
ocrTB.Invoke(showText);
}
}
con.Close();
}
else
{
MessageBox.Show("No character found!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
#endregion
Since it has been a while, I'm hoping you found your answer, but I'm going to guess that you needed to set the file format when you're saving a jpeg:
area.Save(#"C:\Users\Shen\Desktop\LenzOCR\TempFolder\tempPic.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
Past that, I can't remember if the picturebox control is double buffered or not which could be the problem (if it's not, you might not be able to access it for saving purposes while it is being rendered, but if you make a copy of area before setting the picturebox3.Image property that would fix that issue):
Bitmap SavingObject=new Bitmap(area);
picturebox3.Image=area;
SavingObject.Save(#"C:\Users\Shen\Desktop\LenzOCR\TempFolder\tempPic.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
Anyway, I hope you ended up finding your solution (considering it's been a couple months since this was posted).
This looks like a copy of this question:
c# A generic error occurred in GDI+
Same code, same error, same author.
Can't see any difference. But maybe I'm missing something.