Drawing and Saving an Image - c#

I am in the process of developing an app that will be later integrated with another app I developed some time ago.
Basically, this app will generate an image file of X and Y dimensions with a grid printed on it, of which the user also specifies it's interval.
I've done this form so far, but I am having difficulty deciding what the best way to generate an actual image with the proper dimensions and grid spacing should be.
I don't want to save the image that is displayed on the form because it is only a representation and could very well be extremely dissimilar from the final product.
So I guess my question is, what do you think the best way is to generate a black and white image when I click "save"?
Also, I have no need to see the image being saved, I just want to generate and save it behind the scenes.
Here is the "draw" button click event
private void btnDraw_Click(object sender, EventArgs e)
{
this.Width = 560;
using (g = pb.CreateGraphics())
{
g.Clear(Color.White);
PaintCanvass canvass = new PaintCanvass();
canvass.Width = Convert.ToDouble(tbWidth.Text);
canvass.Height = Convert.ToDouble(tbHeight.Text);
canvass.Resolution = Convert.ToInt32(cbResolution.Text.Substring(0,3));
canvass.UOM = cbUOM.Text;
canvass.Interval = Convert.ToInt32(tbInterval.Text);
Pen pencil = new Pen(Color.Black, 2);
int hpfact = Convert.ToInt32((double)pb.Height / (double)canvass.horizontalLinesQuantity);
int hp = hpfact;
for (int i = 0; i < canvass.horizontalLinesQuantity-1; i++)
{
g.DrawLine(pencil, new Point(0, hp), new Point(pb.Width, hp));
hp = hp + hpfact;
}
int vpfact = Convert.ToInt32((double)pb.Width / (double)canvass.verticalLinesQuantity);
int vp = vpfact;
for (int i = 0; i < canvass.verticalLinesQuantity-1; i++)
{
g.DrawLine(pencil, new Point(vp, 0), new Point(vp, pb.Height));
vp = vp + vpfact;
}
canvass = null;
And here is my PaintCanvass class which seems to just be ending up as a container for properties for now
class PaintCanvass
{
public double Width { get; set; }
public double Height { get; set; }
public string UOM { get; set; }
public int Resolution { get; set; }
public int Interval { get; set; } = 50;
public int hdots
{
get
{
if (this.UOM == "mm")
{
return Convert.ToInt32(Width * 0.03937008F * Resolution);
}
else
{
return Convert.ToInt32(Width * Resolution);
};
}
}
public int vdots
{
get
{
// Set the quantity of lines
if (this.UOM == "mm")
{
return Convert.ToInt32(Height * 0.03937008F * Resolution);
}
else
{
return Convert.ToInt32(Height * Resolution);
};
}
}
public int horizontalLinesQuantity
{
get
{
return vdots / this.Interval;
}
}
public int verticalLinesQuantity
{
get
{
return hdots / this.Interval;
}
}
}
Edit: as suggested I went with the bitmap method.
private void btnSave_Click(object sender, EventArgs e)
{
SetupCanvass();
using (Bitmap bmp = new Bitmap(canvass.hdots, canvass.vdots))
{
using (Graphics g = Graphics.FromImage(bmp))
{
using (SolidBrush brush = new SolidBrush(Color.FromArgb(255, 255, 255)))
{
g.FillRectangle(brush, 0, 0, canvass.hdots, canvass.vdots);
}
int hp = canvass.Interval;
for (int i = 0; i < canvass.horizontalLinesQuantity - 1; i++)
{
g.DrawLine(pencil, new Point(0, hp), new Point(canvass.hdots, hp));
hp = hp + canvass.Interval;
}
int vp = canvass.Interval;
for (int i = 0; i < canvass.verticalLinesQuantity - 1; i++)
{
g.DrawLine(pencil, new Point(vp, 0), new Point(vp, canvass.vdots));
vp = vp + canvass.Interval;
}
}
bmp.Save(Path.Combine(Path.GetTempPath(), "labelGrid.png")); //Save image somwhere on disk
}
}

If you want to save an image without displaying a preview, just do something like this:
using (Bitmap bmp = new Bitmap(500, 500))
{
using (Graphics g = Graphics.FromImage(bmp))
{
//Draw your stuff directly onto the bitmap here
}
bmp.Save("C:\\image.bmp"); //Save image somwhere on disk
}

Related

Creating array in loop raise an OutOfMemoryException

I'm working on a software in C# used to manipulate images. I have a lot of images (more than 11000) and when I execute my program after a few minutes, I have an "OutOfMemoryException"
There is my code :
private void GenerateImages()
{
try
{
Parallel.ForEach(listImagesStart, startImg =>
{
bool docontinue = true;
try
{
startImg.LoadImage(_baseFileResults);
}
catch
{
docontinue = false;
}
if (docontinue)
{
//Save image as file
startImg.Save();
// Do rotate
MyImg lastRotate = baseImg;
MyImg imgtmp;
String[] tabRotate = new String[3] { "_90", "_180", "_270"};
foreach (String rotate in tabRotate)
{
imgtmp = new GenImg(baseImg.FileName + rotate + baseImg.FileExtension);
imgtmp.LoadImage(lastRotate);
imgtmp.Rotate90();
imgtmp.Save();
lastRotate = imgtmp;
}
startImg.Dispose();
imgtmp.Dispose();
}
});
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
#if DEBUG
MessageBox.Show(e.StackTrace, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
#endif
}
}
And MyImg :
class myImg
{
public Byte[] Matrix;
public int Height;
public int Width;
public void LoadImage(String filePath)
{
// create new Matrix/Heigth/Width from file
}
public void LoadImage(myImg img)
{
Matrix = new Byte[img.Matrix.Length];
Array.Copy(img.Matrix, Matrix, img.Matrix.Length);
Height = img.Height;
Width = img.Width;
}
public void Rotate90()
{
// Save before
int tmpWidth = Height;
int tmpHeight = Width;
Byte[] tmpMatrix = new Byte[Matrix.Length];
for (int r = 0; r < tmpHeight; r++)
{
for (int c = 0; c < tmpWidth; c++)
{
int prevR = Height - c - 1;
int prevC = r;
tmpMatrix[c + r * tmpWidth] = Matrix[prevC + prevR * Width];
}
}
// Copy new image
Array.Copy(tmpMatrix, Matrix, Matrix.Length);
Width = tmpWidth;
Height = tmpHeight;
}
public void Dispose()
{
SavePath = null;
Matrix = null;
Points = null;
Width = 0;
Height = 0;
GC.Collect();
}
}
The SystemOutOfMemoryException occurs at instructionnew Byte[Length]. I think it's I create too many array but I don't know what to do.
The main issue is that listImagesStart keeps reference of each startImg item. This will keep GC from freeing memory allocated by myImg.LoadImage (with the array Matrix).
A quick solution : you can set Matrix to null to recycle the memory.
public void UnLoadImage()
{
Matrix = null ; // this will allow GC to recycle memory used by Matrix
}
then (I removed the useless docontinue variable) :
try
{
startImg.LoadImage(_baseFileResults);
//Save image as file
startImg.Save();
// Do rotate
MyImg lastRotate = baseImg;
MyImg imgtmp;
String[] tabRotate = new String[3] { "_90", "_180", "_270"};
foreach (String rotate in tabRotate)
{
imgtmp = new GenImg(baseImg.FileName + rotate + baseImg.FileExtension);
imgtmp.LoadImage(lastRotate);
imgtmp.Rotate90();
imgtmp.Save();
lastRotate = imgtmp;
}
startImg.Dispose();
imgtmp.Dispose();
}
catch
{
}
finally
{
startImg.Unload(); // Here is the trick
}

Drawing a Chart for non-numerical variables in C# [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have a issue with chart drawing in my Windows form application project.
I want to draw a chart like this:
http://upload7.ir/imgs/2014-12/84930837744513480976.jpg
the words in axis X and axis Y is related and that letters in colorful rectangles are each relation's value. I want a chart exactly like this.
anyone can help me to draw something like that?
I''l be thankful.
Regards.
Here is a class AreaChart which draws a chart like the one you showed.
Here is what it looks like, with the built-in values:
Add the class to your project and compile. It'll show up in the toolbox and you can place it on your form. (Do a Backup of your project before you do that!)
You can set many values in the designer or in code, including the dimensions, BackColor, Font, and Labels.. Set the Colors and Texts in code using the methods provided!
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
class AreaChart : Panel
{
[Category("Appearance"), Description("Padding around the ChartArea")]
public Padding ChartPadding { get; set; }
[Category("Appearance"),
Description("Axixs Origin offsets from Bottom Left of the Chart")]
public Point AxisOriginOffset { get; set; }
[Category("Appearance"),Description("Number of Rows")]
public int RowNum { get; set; }
[Category("Appearance"), Description("Number of Columns")]
public int ColNum { get; set; }
[Category("Appearance"), Description("Labeltexts for Y-Axis")]
public string[] labelsY { get; set; }
[Category("Appearance"), Description("Labeltexts for X-Axis")]
public string[] labelsX { get; set; }
Color[][] colors { get; set; }
string[][] texts { get; set; }
Rectangle chartArea = Rectangle.Empty;
Point axisOrigin = Point.Empty
public void Init()
{
chartArea = new Rectangle(ChartPadding.Left, ChartPadding.Top,
this.Width - ChartPadding.Left - ChartPadding.Right,
this.Height - ChartPadding.Top - ChartPadding.Bottom);
axisOrigin = new Point(AxisOriginOffset.X, this.Height - AxisOriginOffset.Y);
colors = new Color[RowNum][];
for (int r = 0; r < RowNum; r++) colors[r] = new Color[ColNum];
texts = new string[RowNum][];
for (int r = 0; r < RowNum; r++) texts[r] = new string[ColNum];
labelsX = new string[ColNum]; //*
labelsY = new string[RowNum]; //*
}
public AreaChart()
{
ChartPadding = new Padding(80, 40, 40, 40);
AxisOriginOffset = new Point(60, 20);
RowNum = 3;
ColNum = 2;
BackColor = Color.AntiqueWhite;
Init();
}
protected override void OnPaint(PaintEventArgs e)
{
if (this.DesignMode) Init(); // make the designer show the current
if (this.DesignMode) InitDemo(); // ...sizes, colors and texts
int x = chartArea.X;
int y = chartArea.Y;
SizeF tSize = e.Graphics.MeasureString("XX", this.Font, 9999);
int th = (int)tSize.Height / 2;
int tw = (int)tSize.Width / 2;
int h = chartArea.Height / RowNum;
int w = chartArea.Width / ColNum; e.Graphics.Clear(BackColor);
e.Graphics.DrawLine(Pens.Black, axisOrigin,
new Point(axisOrigin.X, chartArea.Top));
e.Graphics.DrawLine(Pens.Black, axisOrigin,
new Point( chartArea.Right, axisOrigin.Y));
for (int r = 0; r < RowNum; r++)
for (int c = 0; c < ColNum; c++)
{
e.Graphics.FillRectangle(new SolidBrush(colors[r][c]),
x + c * w, y + r * h, w, h);
e.Graphics.DrawRectangle(Pens.Black, x + c * w, y + r * h, w, h);
e.Graphics.DrawString(texts[r][c], this.Font, Brushes.Black,
x + c * w + w / 2 - tw, y + r * h + h / 2 - th);
}
for (int r = 0; r < RowNum; r++)
e.Graphics.DrawString(labelsY[r], this.Font, Brushes.Black,
AxisOriginOffset.X - tw * 2, y + r * h + h / 2 - th); //*
for (int c = 0; c < ColNum; c++)
e.Graphics.DrawString(labelsX[c], this.Font, Brushes.Black,
x + c * w + w / 2 - tw, axisOrigin.Y ); //*
base.OnPaint(e);;
}
public void setColor (int row, int col, Color color)
{
try
{
colors[row][col] = color;
} catch { throw new Exception("setColor : array index out of bounds!"); }
}
public void setText(int row, int col, string text)
{
try
{
texts[row][col] = text;
} catch { throw new Exception("setText: array index out of bounds!"); }
}
public void setLabelX(int col, string text) //*
{
try
{
labelsX[col] = text;
} catch { throw new Exception("array index out of bounds!"); }
}
public void setLabelY(int row, string text) //*
{
try
{
labelsY[row] = text;
} catch { throw new Exception("array index out of bounds!"); }
}
public void InitDemo()
{
setColor(0, 0, Color.Plum);
setColor(1, 0, Color.GreenYellow);
setColor(2, 0, Color.Gold);
setColor(0, 1, Color.LightSkyBlue);
setColor(1, 1, Color.NavajoWhite);
setColor(2, 1, Color.Pink);
setText(0, 0, "AA");
setText(1, 0, "BA");
setText(2, 0, "CA");
setText(0, 1, "AB");
setText(1, 1, "BB");
setText(2, 1, "BC");
setLabelY(0, "A"); //*
setLabelY(1, "B"); //*
setLabelY(2, "C"); //*
setLabelX(0, "A"); //*
setLabelX(1, "B"); //*
}
}
After your Form's Initializecomponent() you should call
areaChart1.Init();
areaChart1.InitDemo();
to display the demo chart I show. To change it use calls like these:
areaChart1.ColNum = 3;
areaChart1.Init();
areaChart1.InitDemo();
areaChart1.setColor(0, 2, Color.Yellow);
areaChart1.setLabelY(2, "ZZ");
//..
Your question is pretty vague, but if you want EXACTLY that chart, does that mean you don't need the values to be dynamic? If so, wouldn't the simplest solution be to save it as an image and display the image in your application where you need it. Obviously this won't work if you need the values or colors to be dynamic.

OpenCv: Finding multiple matches

I have the following, but I can't figure out how to find ALL the matches in a source image.
static void Main()
{
using (var template = Cv.LoadImage(#"images\logo.png", LoadMode.GrayScale))
using (var source = Cv.LoadImage(#"images\manyLogos.png", LoadMode.GrayScale))
using (var sourceColour = Cv.LoadImage(#"images\manyLogos.png", LoadMode.Color))
{
var width = source.Width - template.Width + 1;
var height = source.Height - template.Height + 1;
using (var result = Cv.CreateImage(Cv.Size(width, height), BitDepth.F32, 1))
{
Cv.MatchTemplate(source, template, result, MatchTemplateMethod.SqDiff);
var THRESHOLD = 0.08D;
double minVal, maxVal;
CvPoint minLoc, maxLoc;
Cv.MinMaxLoc(result, out minVal, out maxVal, out minLoc, out maxLoc);
var outlineColor = (minVal > THRESHOLD) ? CvColor.Green : CvColor.Red;
Cv.Rectangle(sourceColour, Cv.Point(minLoc.X, minLoc.Y), Cv.Point(minLoc.X + template.Width, minLoc.Y + template.Height), outlineColor, 1, 0, 0);
}
using (var window = new CvWindow("Test"))
{
while (CvWindow.WaitKey(10) < 0)
{
window.Image = sourceColour;
}
}
}
}
I can outline the best match, just not all the matches. I need to get all the matches somehow.
Using matchTemplate method, your output image will give you pixels values which represents how well your template is matched at this specific location. In you case, the lower the value, the best the match, since you used MatchTemplateMethod.SqDiff.
You problem is that when you use the minMaxLoc function, you get what you asks for, which is the best match in this case, the min).
All matches are the pixels whose value are under the threshold that you set up.
Since I'm not used to csharp, here is how it would go in C++, you can do the translation:
// after your call to MatchTemplate
float threshold = 0.08;
cv::Mat thresholdedImage;
cv::threshold(result, thresholdedImage, threshold, 255, CV_THRESH_BINARY);
// the above will set pixels to 0 in thresholdedImage if their value in result is lower than the threshold, to 255 if it is larger.
// in C++ it could also be written cv::Mat thresholdedImage = result < threshold;
// Now loop over pixels of thresholdedImage, and draw your matches
for (int r = 0; r < thresholdedImage.rows; ++r) {
for (int c = 0; c < thresholdedImage.cols; ++c) {
if (!thresholdedImage.at<unsigned char>(r, c)) // = thresholdedImage(r,c) == 0
cv::circle(sourceColor, cv::Point(c, r), template.cols/2, CV_RGB(0,255,0), 1);
}
}
Translating from C++ and using OpenCvSharp wrapper, the above code, replacing minMaxLoc lines, worked for me:
double threshold=0.9
var thresholdImage=Cv.CreateImage(newImageSize, BitDepth.F32,1);
Cv.Threshold(result, thresholdImage, threshold, 255, ThresholdType.Binary);
for (int r = 0; r < thresholdImage.GetSize().Height; r++)
{
for (int c = 0; c < thresholdImage.GetSize().Width; c++)
{
if (thresholdImage.GetRow(r)[c].Val0 > 0)
{
Cv.Rectangle(soruceColour, Cv.Point(c, r), Cv.Point(c + template.Width, r + template.Height), CvColor.Red, 1, 0, 0);
}
}
}
here is the solution using Min_Max and Match_Template methods. hope it will help.
public void multipleTemplateMatch(string SourceImages, string tempImage)
{
Image<Bgr, byte> image_source = new Image<Bgr, byte>(SourceImages);
Image<Bgr, byte> image_partial1 = new Image<Bgr, byte>(tempImage);
double threshold = 0.9;
ImageFinder imageFinder = new ImageFinder(image_source, image_partial1, threshold);
imageFinder.FindThenShow();
}
and here is the class which will help.
class ImageFinder
{
private List<Rectangle> rectangles;
public Image<Bgr, byte> BaseImage { get; set; }
public Image<Bgr, byte> SubImage { get; set; }
public Image<Bgr, byte> ResultImage { get; set; }
public double Threashold { get; set; }
public List<Rectangle> Rectangles
{
get { return rectangles; }
}
public ImageFinder(Image<Bgr, byte> baseImage, Image<Bgr, byte> subImage, double threashold)
{
rectangles = new List<Rectangle>();
BaseImage = baseImage;
SubImage = subImage;
Threashold = threashold;
}
public void FindThenShow()
{
FindImage();
DrawRectanglesOnImage();
ShowImage();
}
public void DrawRectanglesOnImage()
{
ResultImage = BaseImage.Copy();
foreach (var rectangle in this.rectangles)
{
ResultImage.Draw(rectangle, new Bgr(Color.Blue), 1);
}
}
public void FindImage()
{
rectangles = new List<Rectangle>();
using (Image<Bgr, byte> imgSrc = BaseImage.Copy())
{
while (true)
{
using (Image<Gray, float> result = imgSrc.MatchTemplate(SubImage, TemplateMatchingType.CcoeffNormed))
{
double[] minValues, maxValues;
Point[] minLocations, maxLocations;
result.MinMax(out minValues, out maxValues, out minLocations, out maxLocations);
if (maxValues[0] > Threashold)
{
Rectangle match = new Rectangle(maxLocations[0], SubImage.Size);
imgSrc.Draw(match, new Bgr(Color.Blue), -1);
rectangles.Add(match);
}
else
{
break;
}
}
}
}
}
public void ShowImage()
{
Random rNo = new Random();
string outFilename = "matched Templates" + rNo.Next();
CvInvoke.Imshow(outFilename, ResultImage);
}
}
if you find this helpful please vote is as useful.
thanks

DrawImage fails to position sliced images correctly

For a couple of days now I've tried to figure out why my nine-slice code does not work as expected. As far as I can see, there seems to be an issue with the Graphics.DrawImage method which handles my nine slice images incorrectly. So my problem is how to compensate for the incorrect scaling that is performed when running my code on the compact framework. I might add that this code of course works perfectly when running in the full framework environment. The problem only occurs when scaling the image to a larger image not the other way around. Here is the snippet:
public class NineSliceBitmapSnippet
{
private Bitmap m_OriginalBitmap;
public int CornerLength { get; set; }
/// <summary>
/// Initializes a new instance of the NineSliceBitmapSnippet class.
/// </summary>
public NineSliceBitmapSnippet(Bitmap bitmap)
{
CornerLength = 5;
m_OriginalBitmap = bitmap;
}
public Bitmap ScaleSingleBitmap(Size size)
{
Bitmap scaledBitmap = new Bitmap(size.Width, size.Height);
int[] horizontalTargetSlices = Slice(size.Width);
int[] verticalTargetSlices = Slice(size.Height);
int[] horizontalSourceSlices = Slice(m_OriginalBitmap.Width);
int[] verticalSourceSlices = Slice(m_OriginalBitmap.Height);
using (Graphics graphics = Graphics.FromImage(scaledBitmap))
{
using (Brush brush = new SolidBrush(Color.Fuchsia))
{
graphics.FillRectangle(brush, new Rectangle(0, 0, size.Width, size.Height));
}
int horizontalTargetOffset = 0;
int verticalTargetOffset = 0;
int horizontalSourceOffset = 0;
int verticalSourceOffset = 0;
for (int x = 0; x < horizontalTargetSlices.Length; x++)
{
verticalTargetOffset = 0;
verticalSourceOffset = 0;
for (int y = 0; y < verticalTargetSlices.Length; y++)
{
Rectangle destination = new Rectangle(horizontalTargetOffset, verticalTargetOffset, horizontalTargetSlices[x], verticalTargetSlices[y]);
Rectangle source = new Rectangle(horizontalSourceOffset, verticalSourceOffset, horizontalSourceSlices[x], verticalSourceSlices[y]);
graphics.DrawImage(m_OriginalBitmap, destination, source, GraphicsUnit.Pixel);
verticalTargetOffset += verticalTargetSlices[y];
verticalSourceOffset += verticalSourceSlices[y];
}
horizontalTargetOffset += horizontalTargetSlices[x];
horizontalSourceOffset += horizontalSourceSlices[x];
}
}
return scaledBitmap;
}
public int[] Slice(int length)
{
int cornerLength = CornerLength;
if (length <= (cornerLength * 2))
throw new Exception("Image to small for sliceing up");
int[] slices = new int[3];
slices[0] = cornerLength;
slices[1] = length - (2 * cornerLength);
slices[2] = cornerLength;
return slices;
}
}
So, my question is, does anybody now how I could compensate the incorrect scaling?
/Dan
After some more trial and error I've finally found a solution to my problem. The scaling problems has always been to the top-center, right-center, bottom-center and left-center slices since they're always stretched in only one direction according to the logic of nine slice scaling. If I apply a temporarely square stretch to those slices before applying the correct stretch the final bitmap will be correct. Once again the problem is only visible in the .Net Compact Framework of a Windows CE device (Smart Device). Here's a snippet with code adjusting for the bug in CF. My only concern now is that the slices that get square stretched will take much more memory due to the correction code. On the other hand this step is only a short period of time so I might get away with it. ;)
public class NineSliceBitmapSnippet
{
private Bitmap m_OriginalBitmap;
public int CornerLength { get; set; }
public NineSliceBitmapSnippet(Bitmap bitmap)
{
CornerLength = 5;
m_OriginalBitmap = bitmap;
}
public Bitmap Scale(Size size)
{
if (m_OriginalBitmap != null)
{
return ScaleSingleBitmap(size);
}
return null;
}
public Bitmap ScaleSingleBitmap(Size size)
{
Bitmap scaledBitmap = new Bitmap(size.Width, size.Height);
int[] horizontalTargetSlices = Slice(size.Width);
int[] verticalTargetSlices = Slice(size.Height);
int[] horizontalSourceSlices = Slice(m_OriginalBitmap.Width);
int[] verticalSourceSlices = Slice(m_OriginalBitmap.Height);
using (Graphics graphics = Graphics.FromImage(scaledBitmap))
{
using (Brush brush = new SolidBrush(Color.Fuchsia))
{
graphics.FillRectangle(brush, new Rectangle(0, 0, size.Width, size.Height));
}
int horizontalTargetOffset = 0;
int verticalTargetOffset = 0;
int horizontalSourceOffset = 0;
int verticalSourceOffset = 0;
for (int x = 0; x < horizontalTargetSlices.Length; x++)
{
verticalTargetOffset = 0;
verticalSourceOffset = 0;
for (int y = 0; y < verticalTargetSlices.Length; y++)
{
Rectangle destination = new Rectangle(horizontalTargetOffset, verticalTargetOffset, horizontalTargetSlices[x], verticalTargetSlices[y]);
Rectangle source = new Rectangle(horizontalSourceOffset, verticalSourceOffset, horizontalSourceSlices[x], verticalSourceSlices[y]);
bool isWidthAffectedByVerticalStretch = (y == 1 && (x == 0 || x == 2) && destination.Height > source.Height);
bool isHeightAffectedByHorizontalStretch = (x == 1 && (y == 0 || y == 2) && destination.Width > source.Width);
if (isHeightAffectedByHorizontalStretch)
{
BypassDrawImageError(graphics, destination, source, Orientation.Horizontal);
}
else if (isWidthAffectedByVerticalStretch)
{
BypassDrawImageError(graphics, destination, source, Orientation.Vertical);
}
else
{
graphics.DrawImage(m_OriginalBitmap, destination, source, GraphicsUnit.Pixel);
}
verticalTargetOffset += verticalTargetSlices[y];
verticalSourceOffset += verticalSourceSlices[y];
}
horizontalTargetOffset += horizontalTargetSlices[x];
horizontalSourceOffset += horizontalSourceSlices[x];
}
}
return scaledBitmap;
}
private void BypassDrawImageError(Graphics graphics, Rectangle destination, Rectangle source, Orientation orientationAdjustment)
{
Size adjustedSize = Size.Empty;
switch (orientationAdjustment)
{
case Orientation.Horizontal:
adjustedSize = new Size(destination.Width, destination.Width);
break;
case Orientation.Vertical:
adjustedSize = new Size(destination.Height, destination.Height);
break;
default:
break;
}
using (Bitmap quadScaledBitmap = new Bitmap(adjustedSize.Width, adjustedSize.Height))
{
using (Graphics tempGraphics = Graphics.FromImage(quadScaledBitmap))
{
tempGraphics.Clear(Color.Fuchsia);
tempGraphics.DrawImage(m_OriginalBitmap, new Rectangle(0, 0, adjustedSize.Width, adjustedSize.Height), source, GraphicsUnit.Pixel);
}
graphics.DrawImage(quadScaledBitmap, destination, new Rectangle(0, 0, quadScaledBitmap.Width, quadScaledBitmap.Height), GraphicsUnit.Pixel);
}
}
public int[] Slice(int length)
{
int cornerLength = CornerLength;
if (length <= (cornerLength * 2))
throw new Exception("Image to small for sliceing up");
int[] slices = new int[3];
slices[0] = cornerLength;
slices[1] = length - (2 * cornerLength);
slices[2] = cornerLength;
return slices;
}
}

namespace doesn't exist

I would like to try out a code in Microsoft Visual C# Express Edition and I'm getting this error:
The type or namespace name 'Properties' does not exist in the namespace 'EducationalSuite.Core' (are you missing an assembly reference?)
I right click the Reference but I didn't find the "Properties" either the "EducationalSuite.Core".
Here is the code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Media;
using System.Resources;
namespace EducationalSuite.Core.Plugins
{
public delegate void RectangleItemClickedDelegate(Rectangle rect, int index);
public partial class GeoSafariItem : Control
{
protected List<Rectangle> lastFlashingItems = new List<Rectangle>();
protected int lastHeight = 0;
private Image imageFile = null;
protected List<Rectangle> hotspots = new List<Rectangle>();
protected Dictionary<int, string> textItems = new Dictionary<int, string>();
protected Dictionary<int, FileInfo> audioItems = new Dictionary<int, FileInfo>();
protected Rectangle lastRectangle;
protected int selectedIndex = 0;
protected int countItemsLeft = 6;
protected int countItemsRight = 6;
protected int imageOffsetTop = 0;
protected int imageOffsetBottom = 0;
protected bool paintHotSpots = false, colorSwitch = false, paintItemLabels = false;
protected Timer timer = new Timer();
public event RectangleItemClickedDelegate HotspotClick;
public event RectangleItemClickedDelegate QuestionItemClick;
public event RectangleItemClickedDelegate QuestionItemRightClick;
protected void OnHotspotClick(Rectangle rect, int index)
{
if (HotspotClick != null)
{
HotspotClick(this.RectangleToScreen(rect), index);
}
}
protected void OnQuestionItemRightClick(Rectangle rect, int index)
{
if (QuestionItemRightClick != null)
{
QuestionItemRightClick(this.RectangleToScreen(rect), index);
}
}
protected void OnQuestionItemClick(Rectangle rect, int index)
{
if (QuestionItemClick != null)
{
QuestionItemClick(this.RectangleToScreen(rect), index);
}
}
public GeoSafariItem()
{
this.imageFile = EducationalSuite.Core.Properties.Resources.singlepixel;
timer.Interval = 100;
timer.Tick += new EventHandler(timer_Tick);
timer.Enabled = true;
this.MouseUp += new MouseEventHandler(GeoSafariItem_MouseUp);
// Activates double buffering
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
SetStyle(ControlStyles.ResizeRedraw, true);
this.DoubleBuffered = true;
//InitializeComponent();
}
public void SetItemText(int index, string text)
{
if (string.IsNullOrEmpty(text))
{
if (this.textItems.ContainsKey(index)) textItems.Remove(index);
}
else
{
this.textItems[index] = text;
}
if (PaintItemLabels)
{
this.Invalidate();
}
}
public string GetItemText(int index)
{
if (this.textItems.ContainsKey(index))
{
return this.textItems[index];
}
else
{
return string.Empty;
}
}
public void SetItemAudio(int index, FileInfo file)
{
if ((file == null) && !file.Exists)
{
if (this.audioItems.ContainsKey(index)) audioItems.Remove(index);
}
else
{
this.audioItems[index] = file;
}
}
public FileInfo GetItemAudio(int index)
{
if (this.audioItems.ContainsKey(index))
{
return this.audioItems[index];
}
else
{
return null;
}
}
#region Recording Regions
bool isRecording = false;
int recordingIndex = 0;
Point recordTopLeft = Point.Empty;
Point recordBottomRight = Point.Empty;
List<Rectangle> recordedRectangles = new List<Rectangle>();
public void StartRecording()
{
isRecording = true;
recordingIndex = 0;
selectedIndex = 0;
recordedRectangles.Clear();
this.MouseUp += new MouseEventHandler(GeoSafariItemRecord_MouseUp);
this.Invalidate();
}
public List<Rectangle> FinishRecording()
{
isRecording = false;
this.MouseUp -= new MouseEventHandler(GeoSafariItemRecord_MouseUp);
this.Invalidate();
this.Hotspots.Clear();
foreach (Rectangle r in recordedRectangles)
{
this.Hotspots.Add(r);
}
return recordedRectangles;
}
private void GeoSafariItemRecord_MouseUp(object sender, MouseEventArgs e)
{
if (isRecording)
{
Rectangle size = SizeRect;
double ratio = (double)imageFile.Height / (double)size.Height;
if (recordTopLeft == Point.Empty)
{
recordTopLeft = new Point(
(int)(((double)e.Location.X - (double)size.Left) * ratio),
(int)(((double)e.Location.Y - (double)size.Top) * ratio)
);
}
else
{
recordBottomRight = new Point(
(int)(((double)e.Location.X - (double)size.Left) * ratio),
(int)(((double)e.Location.Y - (double)size.Top) * ratio)
);
Rectangle r = new Rectangle(recordTopLeft,
new Size(recordBottomRight.X - recordTopLeft.X, recordBottomRight.Y - recordTopLeft.Y));
this.recordedRectangles.Add(r);
recordingIndex++;
selectedIndex++;
recordTopLeft = Point.Empty;
recordBottomRight = Point.Empty;
}
}
this.Invalidate();
}
#endregion
void timer_Tick(object sender, EventArgs e)
{
colorSwitch = !colorSwitch;
if (lastRectangle.Width > 0)
{
this.Invalidate(lastRectangle);
}
else
{
this.Invalidate();
}
}
private Rectangle SizeRect
{
get
{
int rw, rh,
cw = (this.Width - 42),
ch = (this.Height - 2),
ox = 21,
oy = 1;
rw = cw;
rh = ch;
double imageRatio = (double)imageFile.Width / (double)imageFile.Height;
double controlRatio = (double)cw / (double)ch;
if (controlRatio > imageRatio)
{
rw = (int)Math.Round((double)rh * imageRatio);
ox += Math.Abs(rw - cw) / 2;
}
else if (controlRatio < imageRatio)
{
rh = (int)Math.Round((double)rw / imageRatio);
oy += Math.Abs(rh - ch) / 2;
}
return new Rectangle(ox, oy, rw, rh);
}
}
void GeoSafariItem_MouseUp(object sender, MouseEventArgs e)
{
Rectangle size = SizeRect;
for (int i = 0; i < hotspots.Count; i++)
{
Rectangle hotspot = hotspots[i];
double ratio = (double)size.Height / (double)imageFile.Height;
Rectangle adjustedRectange = new Rectangle(
size.Left + (int)(hotspot.X * ratio),
size.Top + (int)(hotspot.Y * ratio),
(int)(hotspot.Width * ratio),
(int)(hotspot.Height * ratio));
if (adjustedRectange.Contains(e.Location))
{
OnHotspotClick(hotspot, i);
return;
}
}
for (int i = 0; i < lastFlashingItems.Count; i++)
{
if (lastFlashingItems[i].Contains(e.Location))
{
if (e.Button == MouseButtons.Right)
OnQuestionItemRightClick(lastFlashingItems[i], i);
else
OnQuestionItemClick(lastFlashingItems[i], i);
return;
}
}
}
public List<Rectangle> Hotspots
{
get { return hotspots; }
}
public Image ImageFile
{
get { return imageFile; }
set
{
imageFile = value;
lastFlashingItems.Clear();
this.Invalidate();
}
}
public int SelectedIndex
{
get { return selectedIndex; }
set { selectedIndex = value; this.Invalidate(); }
}
public int CountItemsLeft
{
get { return countItemsLeft; }
set
{
countItemsLeft = value;
lastFlashingItems.Clear();
this.Invalidate();
}
}
public int CountItemsRight
{
get { return countItemsRight; }
set
{
countItemsRight = value;
lastFlashingItems.Clear();
this.Invalidate();
}
}
public int ImageOffsetTop
{
get { return imageOffsetTop; }
set
{
imageOffsetTop = value;
lastFlashingItems.Clear();
this.Invalidate();
}
}
public int ImageOffsetBottom
{
get { return imageOffsetBottom; }
set
{
imageOffsetBottom = value;
lastFlashingItems.Clear();
this.Invalidate();
}
}
public bool PaintHotSpots
{
get { return paintHotSpots; }
set { paintHotSpots = value; this.Invalidate(); }
}
public bool PaintItemLabels
{
get { return paintItemLabels; }
set { paintItemLabels = value; this.Invalidate(); }
}
protected override void OnPaint(PaintEventArgs pe)
{
Graphics g = pe.Graphics;
string itemText;
SizeF sizeItemText;
double topOffset = imageOffsetTop;
double bottomOffset = imageOffsetBottom;
double topOffsetPct = (double)topOffset / (double)imageFile.Height;
double bottomOffsetPct = (double)bottomOffset / (double)imageFile.Height;
Rectangle size = SizeRect;
SolidBrush brush = new SolidBrush(this.BackColor);
g.FillRectangle(brush, 0, 0, this.Width - 1, this.Height - 1);
g.FillRectangle(Brushes.Ivory, size.X - 25, size.Y, size.Width + 50, size.Height);
g.DrawRectangle(Pens.DarkKhaki, size.X - 25, size.Y - 1, size.Width + 50, size.Height + 1);
g.DrawImage(imageFile, size.X, size.Y, size.Width, size.Height);
Rectangle rect, rectItemText;
Brush selectedColor = (colorSwitch ? Brushes.Crimson : Brushes.Red);
topOffset = topOffsetPct * size.Height;
bottomOffset = bottomOffsetPct * size.Height;
int tmpHeight = (size.Height - (int)topOffset - (int)bottomOffset) / countItemsLeft;
if (size.Height != this.lastHeight || this.lastFlashingItems.Count == 0)
{
lastHeight = size.Height;
lastFlashingItems.Clear();
int actualIndex = 0;
for (int i = 0; i < countItemsLeft; i++)
{
int yy = size.Y + (tmpHeight * i) + (int)topOffset;
int xx = size.X - 18;
rect = new Rectangle(xx, yy, 16, 8);
this.lastFlashingItems.Add(rect);
g.FillRectangle((actualIndex == selectedIndex ? selectedColor : Brushes.Khaki), rect);
g.DrawRectangle(Pens.DarkKhaki, rect);
if (actualIndex == selectedIndex)
{
lastRectangle = rect;
}
itemText = this.GetItemText(actualIndex);
if (PaintItemLabels && !string.IsNullOrEmpty(itemText))
{
// Draw Text next to each notch
sizeItemText = g.MeasureString(itemText, this.Font);
int xxx = size.X + 10;
rectItemText = new Rectangle(xxx, yy, Convert.ToInt32(sizeItemText.Width), Convert.ToInt32(sizeItemText.Height));
PaintHotspot(g, Color.White, rectItemText, 200);
g.DrawString(itemText, this.Font, Brushes.Black, (float)xxx, (float)yy);
}
actualIndex++;
}
tmpHeight = (size.Height - (int)topOffset - (int)bottomOffset) / countItemsRight;
for (int i = 0; i < countItemsRight; i++)
{
int yy = size.Y + (tmpHeight * i) + (int)topOffset;
int xx = size.X + size.Width + 2;
rect = new Rectangle(xx, yy, 16, 8);
this.lastFlashingItems.Add(rect);
g.FillRectangle((actualIndex == selectedIndex ? selectedColor : Brushes.Khaki), rect);
g.DrawRectangle(Pens.DarkKhaki, rect);
if (actualIndex == selectedIndex)
{
lastRectangle = rect;
}
itemText = this.GetItemText(actualIndex);
if (PaintItemLabels && !string.IsNullOrEmpty(itemText))
{
// Draw Text next to each notch
sizeItemText = g.MeasureString(itemText, this.Font);
int xxx = size.X + size.Width - 10 - Convert.ToInt32(sizeItemText.Width);
rectItemText = new Rectangle(xxx, yy, Convert.ToInt32(sizeItemText.Width), Convert.ToInt32(sizeItemText.Height));
PaintHotspot(g, Color.White, rectItemText, 200);
g.DrawString(itemText, this.Font, Brushes.Black, (float)xxx, (float)yy);
}
actualIndex++;
}
}
else
{
lastHeight = size.Height;
for (int i = 0; i < lastFlashingItems.Count; i++)
{
g.FillRectangle((i == selectedIndex ? selectedColor : Brushes.Khaki), lastFlashingItems[i]);
g.DrawRectangle(Pens.DarkKhaki, lastFlashingItems[i]);
if (i == selectedIndex)
{
lastRectangle = lastFlashingItems[i];
}
}
if (PaintItemLabels)
{
int actualIndex = 0;
for (int i = 0; i < countItemsLeft; i++)
{
itemText = this.GetItemText(actualIndex);
if (!string.IsNullOrEmpty(itemText))
{
int yy = size.Y + (tmpHeight * i) + (int)topOffset;
// Draw Text next to each notch
sizeItemText = g.MeasureString(itemText, this.Font);
int xxx = size.X + 10;
rectItemText = new Rectangle(xxx, yy, Convert.ToInt32(sizeItemText.Width), Convert.ToInt32(sizeItemText.Height));
PaintHotspot(g, Color.White, rectItemText, 200);
g.DrawString(itemText, this.Font, Brushes.Black, (float)xxx, (float)yy);
}
actualIndex++;
}
tmpHeight = (size.Height - (int)topOffset - (int)bottomOffset) / countItemsRight;
for (int i = 0; i < countItemsRight; i++)
{
itemText = this.GetItemText(actualIndex);
if (!string.IsNullOrEmpty(itemText))
{
int yy = size.Y + (tmpHeight * i) + (int)topOffset;
// Draw Text next to each notch
sizeItemText = g.MeasureString(itemText, this.Font);
int xxx = size.X + size.Width - 10 - Convert.ToInt32(sizeItemText.Width);
rectItemText = new Rectangle(xxx, yy, Convert.ToInt32(sizeItemText.Width), Convert.ToInt32(sizeItemText.Height));
PaintHotspot(g, Color.White, rectItemText, 200);
g.DrawString(itemText, this.Font, Brushes.Black, (float)xxx, (float)yy);
}
actualIndex++;
}
}
}
// Calling the base class OnPaint
base.OnPaint(pe);
if (this.isRecording)
{
for (int i = 0; i < this.recordedRectangles.Count; i++)
{
rect = recordedRectangles[i];
double ratio = (double)size.Height / (double)imageFile.Height;
Rectangle adjustedRectange = new Rectangle(
size.Left + (int)(rect.X * ratio),
size.Top + (int)(rect.Y * ratio),
(int)(rect.Width * ratio),
(int)(rect.Height * ratio));
PaintHotspot(g, Color.LightBlue, adjustedRectange, (i + 1).ToString());
}
}
else if (this.paintHotSpots)
{
for (int i = 0; i < hotspots.Count; i++)
{
Rectangle hotspot = hotspots[i];
double ratio = (double)size.Height / (double)imageFile.Height;
Rectangle adjustedRectange = new Rectangle(
size.Left + (int)(hotspot.X * ratio),
size.Top + (int)(hotspot.Y * ratio),
(int)(hotspot.Width * ratio),
(int)(hotspot.Height * ratio));
PaintHotspot(g, Color.LightGreen, adjustedRectange, (i + 1).ToString());
}
}
}
protected virtual void PaintHotspot(Graphics g, Color c, Rectangle hotspot, int alpha)
{
PaintHotspot(g, c, hotspot, alpha, null);
}
protected virtual void PaintHotspot(Graphics g, Color c, Rectangle hotspot, string txt)
{
PaintHotspot(g, c, hotspot, 100, txt);
}
protected virtual void PaintHotspot(Graphics g, Color c, Rectangle hotspot, int alpha, string txt)
{
SolidBrush brush = new SolidBrush(Color.FromArgb(alpha, c));
g.FillRectangle(brush, hotspot);
if (!string.IsNullOrEmpty(txt))
g.DrawString(txt, this.Font, Brushes.DarkGreen, hotspot.Location);
}
}
}
Update
I imagine the following line is causing the error.
this.imageFile = EducationalSuite.Core.Properties.Resources.singlepixel;
The code is referring to a image resource "singlepixel". This image must be in the default resource file of the EducationalSuite.Core assembly. First confirm that you are currently editing the said assembly by opening Project Properties and checking the Default Namespace on the Application page. This should state "EducationalSuite.Core". If this isn't the case, you are most likely missing a reference to the said assembly.
If you have the EducationalSuite.Core project open the easiest way to add the singlepixel resource is to open project properties, Resources tab and creating a new default resource file. From the top open the Add Resource drop down and select existing file or new image depending on whether you have the file already or if you need to create it. Name the resource "singlepixel".
Visual Studio will generate Resources helper class under Properties namespace for you so you can access the resource through the Properties.Resources.singlepixel under EducationalSuite.Core in your code.
Old answer
In general Properties namespace is the namespace which contains application or user specific settings. You can add these settings (and the namespace) by navigating to the Settings tab in the Properties of the project.
Unfortunately it's kind of hard to say more based on this information. Could you provide the piece of code that causes this error?
If you double click the error message the IDE will take you to the line which is causing the error.
Most likely the piece of code is expecting a setting variable which is not added to the project.
Looks like you are missing the Reference. If it is not under References in solution explorer than I would do a file search in windows for "EducationalSuite.Core" to see where it is on the system and add it. You may also be missing the "using" statement? If you hover over the "Properties" text you should get a small drop down that will add the using's for you.
If this does not help, more information would be helpful?
Hope this helps!

Categories

Resources