public Bitmap GetBitmap() { // This pass calculates the pixel intensity contribution from each point and sums them. float[,] pix_intensity = new float[area.Width, area.Height]; int h = area.Height; int w = area.Width; foreach (HeatMapPoint pt in hmpl) { // This approach may introduce aliasing; employing some antialiasing technique would look slightly nicer. int l = (int)Math.Max(pt.X - dotradius, 0); int r = (int)Math.Min(pt.X + dotradius, w - 1); int t = (int)Math.Max(pt.Y - dotradius, 0); int b = (int)Math.Min(pt.Y + dotradius, h - 1); for (int x = l; x <= r; x++) { for (int y = t; y <= b; y++) { pix_intensity[x, y] = pix_intensity[x, y] + PixelIntensity(pt, x, y); } } } List<float> intensities = new List<float>(); for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { intensities.Add(pix_intensity[x, y]); } } intensities.Sort(); gradient = GetGradientFromIntensities(intensities); float min_intensity = intensities[0]; float max_intensity = intensities[intensities.Count - 1]; List<float> nIntensity = new List<float>(); // This pass normalizes the intensities to fall between 0.0 and 1.0. for (int x = 0; x < area.Width; x++) { for (int y = 0; y < area.Height; y++) { pix_intensity[x, y] = Map1DSpace(pix_intensity[x, y], min_intensity, max_intensity, 0.0f, 1.0f); if(pix_intensity[x,y] != 0) nIntensity.Add(pix_intensity[x, y]); } } nIntensity.Sort(); int Idx100 = nIntensity.Count; int[] Idx = new int[4]; for (int rep = 0; rep < nIntensity.Count; rep++) { if (gradient.POINTS[1].Position < nIntensity[rep] && Idx[0] == 0) { Idx[0] = rep - 1; } else if (gradient.POINTS[2].Position < nIntensity[rep] && Idx[1] == 0) { Idx[1] = rep - 1; } else if (gradient.POINTS[3].Position < nIntensity[rep] && Idx[2] == 0) { Idx[2]= rep - 1; } else if (gradient.POINTS[4].Position < nIntensity[rep] && Idx[3] == 0) { Idx[3] = rep - 1; } } fIdx[0] = (float)((float)Idx[0] / (float)Idx100) * 100; fIdx[1] = (float)((float)(Idx[1] - Idx[0]) / (float)Idx100) * 100; fIdx[2] = (float)((float)(Idx[2] - Idx[1]) / (float)Idx100) * 100; fIdx[3] = (float)((float)(Idx[3] - Idx[2]) / (float)Idx100) * 100; fIdx[4] = (float)((float)(Idx100 - Idx[3]) / (float)Idx100) * 100; // This pass constructs the output image. Bitmap bmp = new Bitmap(area); for (int x = 0; x < area.Width; x++) { for (int y = 0; y < area.Height; y++) { Color col = bmp.GetPixel(x, y); if (grayscale) { float pixlum = col.GetBrightness(); col = Color.FromArgb((int)(pixlum * 255.0f), (int)(pixlum * 255.0f), (int)(pixlum * 255.0f)); } if (trimheatless && pix_intensity[x, y] == 0.0f) bmp.SetPixel(x, y, col); else { Color heatcol = IntensityToColor(pix_intensity[x, y]); Color newcol = HeatMap.Lerp(col, heatcol, opacity); bmp.SetPixel(x, y, newcol); } } } // Return the finished image return bmp; }
private Gradient GetGradientFromIntensities(List<float> intensities) { List<float> divs = Gradient.GetDivisionsFromData(intensities, 4); Gradient g = new Gradient(Color.FromArgb(64, 64, 64), Color.FromArgb(255, 0, 0)); // gray to red g.AddPoint(Color.FromArgb(0, 0, 128), divs[0]); // blue g.AddPoint(Color.FromArgb(0, 160, 158), divs[1]); // cyan g.AddPoint(Color.FromArgb(0, 192, 0), divs[2]); // green g.AddPoint(Color.FromArgb(221, 224, 0), divs[3]); // yellow return g; }
private Gradient GetGradientDefault() { Gradient g = new Gradient(Color.FromArgb(64, 64, 64), Color.FromArgb(255, 0, 0)); // gray to red g.AddPoint(Color.FromArgb(0, 0, 128), 0.2f); // blue g.AddPoint(Color.FromArgb(0, 160, 158), 0.4f); // cyan g.AddPoint(Color.FromArgb(0, 192, 0), 0.6f); // green g.AddPoint(Color.FromArgb(221, 224, 0), 0.8f); // yellow return g; }
public Bitmap GetLegend(int width, int height, int max, int middle) { // This pass calculates the pixel intensity contribution from each point and sums them. int labelHeight = 20; int graphWidth = 50; int graphHeight = height - labelHeight; int textWidth = (width - graphWidth) / 2; int legendX = width; int legendY = height; gradient = GetGradientDefault(); // This pass constructs the output image. Bitmap legend = new Bitmap(legendX, legendY); Graphics G = Graphics.FromImage(legend); G.FillRectangle(Brushes.AntiqueWhite, new Rectangle(0, 0, legendX, legendY)); for (int x = 0; x < legendY - labelHeight; x++) { Color heatcol = IntensityToColor((float)(1 - ((float)x / (float)(legendY - labelHeight)))); Color newcol = HeatMap.Lerp(Color.White, heatcol, 0.8f); using (Pen the_pen = new Pen(newcol)) { G.DrawLine(the_pen, textWidth, x + labelHeight, textWidth + graphWidth, x + labelHeight); } } SolidBrush strPen = new SolidBrush(Color.Black); Font drawFont = new Font("arial", 25, FontStyle.Regular); StringFormat stringFormat = new StringFormat(); stringFormat.Alignment = StringAlignment.Center; stringFormat.LineAlignment = StringAlignment.Near; DrawFitString(G, "개체 빈도수 히트맵", drawFont, strPen, new Rectangle(0, 0, legendX, labelHeight), stringFormat); string maxString = string.Format("{0}회", max); string midString = string.Format("{0}회", middle); stringFormat.LineAlignment = StringAlignment.Near; int perStringStartX = textWidth + graphWidth; DrawFitString(G, maxString, drawFont, strPen, new Rectangle(perStringStartX, labelHeight, legendX - perStringStartX, (int)(graphHeight * 0.1)), stringFormat); stringFormat.LineAlignment = StringAlignment.Center; G.DrawString(midString, smallFont, strPen, new Rectangle(perStringStartX, (int)(graphHeight * 0.45) + labelHeight, legendX - perStringStartX, (int)(legendY * 0.1)), stringFormat); stringFormat.LineAlignment = StringAlignment.Far; G.DrawString("0회", smallFont, strPen, new Rectangle(perStringStartX, legendY - (int)(graphHeight * 0.1), legendX - perStringStartX, (int)(legendY * 0.1)), stringFormat); stringFormat.LineAlignment = StringAlignment.Center; string percent; percent = string.Format("{0:F2}%", fIdx[4]); DrawFitString(G, percent, drawFont, strPen, new Rectangle(0, labelHeight, textWidth, (int)(graphHeight * 0.2)), stringFormat); percent = string.Format("{0:F2}%", fIdx[3]); G.DrawString(percent, smallFont, strPen, new Rectangle(0, labelHeight + (int)(graphHeight * 0.2), textWidth, (int)(graphHeight * 0.2)), stringFormat); percent = string.Format("{0:F2}%", fIdx[2]); G.DrawString(percent, smallFont, strPen, new Rectangle(0, labelHeight + (int)(graphHeight * 0.4), textWidth, (int)(graphHeight * 0.2)), stringFormat); percent = string.Format("{0:F2}%", fIdx[1]); G.DrawString(percent, smallFont, strPen, new Rectangle(0, labelHeight + (int)(graphHeight * 0.6), textWidth, (int)(graphHeight * 0.2)), stringFormat); percent = string.Format("{0:F2}%", fIdx[0]); G.DrawString(percent, smallFont, strPen, new Rectangle(0, labelHeight + (int)(graphHeight * 0.8), textWidth, (int)(graphHeight * 0.2)), stringFormat); Pen linePen = new Pen(Color.Black, 1.0f); for (int i = 1; i < 6; i++ ) G.DrawLine(linePen, 0, (float)(labelHeight + (graphHeight * 0.2 * i)), (float)(textWidth), (float)(labelHeight + (graphHeight * 0.2 * i))); return legend; }