private void RenderGraph() { ClearRenderTargetBitmap(_heatMapGraph, Brushes.White); const double xAxisOffset = 250; const double yAxisOffset = 500; const double topOffset = 50; const double rightOffset = 250; var xAxisLength = _heatMapGraph.PixelWidth - (int)xAxisOffset - (int)rightOffset; var yAxisLength = _heatMapGraph.PixelHeight - (int)yAxisOffset - (int)topOffset; const double axisThickness = 10; var axisPen = new Pen(Brushes.Black, axisThickness); var axisTickPen = new Pen(Brushes.Black, axisThickness / 2); DrawHeatMap(); var heatMapRect = new Rectangle { Fill = new ImageBrush(_heatMap) { Stretch = Stretch.Uniform }, Effect = _heatMapColourEffect }; var heatMapRectSize = new Size(xAxisLength, yAxisLength); heatMapRect.Measure(heatMapRectSize); heatMapRect.Arrange(new Rect(new Point(xAxisOffset + 5, topOffset), heatMapRectSize)); _heatMapGraph.Render(heatMapRect); var heatMapKeyWidth = xAxisLength; const int heatMapKeyHeight = 100; var heatMapKeyRect = new Rectangle { Fill = new ImageBrush(DrawHeatKey(heatMapKeyWidth, heatMapKeyHeight)), Effect = _heatMapColourEffect }; var heatMapKeySize = new Size(heatMapKeyWidth, heatMapKeyHeight); heatMapKeyRect.Measure(heatMapKeySize); heatMapKeyRect.Arrange(new Rect(new Point(xAxisOffset + 5, _heatMapGraph.PixelHeight - yAxisOffset + topOffset + 150), heatMapKeySize)); _heatMapGraph.Render(heatMapKeyRect); var drawingVisual = new DrawingVisual(); var textTypeFace = new Typeface(new FontFamily("Arial"), FontStyles.Normal, FontWeights.Normal, FontStretches.Normal); const double headerFontSize = 80d; const double fontSize = 40d; const int numberOfTicks = 10; var fontBrush = Brushes.Black; using (var context = drawingVisual.RenderOpen()) { //Y Axis context.DrawLine(axisPen, new Point(xAxisOffset, topOffset), new Point(xAxisOffset, topOffset + yAxisLength)); //X Axis context.DrawLine(axisPen, new Point(xAxisOffset - 5, topOffset + yAxisLength), new Point(xAxisOffset + xAxisLength + 5, topOffset + yAxisLength)); context.DrawText(new FormattedText(MinValue.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, textTypeFace, headerFontSize, fontBrush), new Point(xAxisOffset + 5, _heatMapGraph.PixelHeight - yAxisOffset + topOffset + 250)); context.DrawText(new FormattedText(MaxValue.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, textTypeFace, headerFontSize, fontBrush), new Point(xAxisOffset + 5 + xAxisLength, _heatMapGraph.PixelHeight - yAxisOffset + topOffset + 250)); context.DrawText(new FormattedText("Time", CultureInfo.InvariantCulture, FlowDirection.LeftToRight, textTypeFace, headerFontSize, fontBrush), new Point(xAxisOffset + (xAxisLength / 2), topOffset + yAxisLength + 60)); var dateDistance = (MaxTimestamp - MinTimestamp).Ticks / numberOfTicks; for (var i = 0; i < numberOfTicks; i++) { var date = MinTimestamp + new TimeSpan(i * dateDistance); var xValue = (1 - ((MaxTimestamp - date).TotalSeconds / (MaxTimestamp - MinTimestamp).TotalSeconds)) * xAxisLength + xAxisOffset; context.DrawLine(axisTickPen, new Point(xValue, topOffset + yAxisLength), new Point(xValue, topOffset + yAxisLength + 20)); context.DrawText(new FormattedText(date.ToString("yyyy/MM/dd HH:mm"), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, textTypeFace, fontSize, fontBrush), new Point(xValue, topOffset + yAxisLength + 10)); } context.PushTransform(new RotateTransform(90)); context.DrawText(new FormattedText("Depth", CultureInfo.InvariantCulture, FlowDirection.LeftToRight, textTypeFace, headerFontSize, fontBrush), new Point((topOffset + (yAxisLength / 2)), -headerFontSize * 2)); context.Pop(); if (_depths != null) foreach (var depthYValue in _depths) { context.DrawText(new FormattedText(depthYValue.Depth.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, textTypeFace, fontSize, fontBrush), new Point(xAxisOffset - 100, topOffset + (depthYValue.YValue / _heatMap.PixelHeight) * yAxisLength)); context.DrawLine(axisTickPen, new Point(xAxisOffset - 25, topOffset + (depthYValue.YValue / _heatMap.PixelHeight) * yAxisLength + (axisTickPen.Thickness / 2)), new Point(xAxisOffset, topOffset + (depthYValue.YValue / _heatMap.PixelHeight) * yAxisLength + (axisTickPen.Thickness / 2))); } } _heatMapGraph.Render(drawingVisual); }
private void RenderGraph() { ClearRenderTargetBitmap(_heatMapGraph, Brushes.White); const double xAxisOffset = 250; const double yAxisOffset = 500; const double topOffset = 50; const double rightOffset = 250; var xAxisLength = _heatMapGraph.PixelWidth - (int)xAxisOffset - (int)rightOffset; var yAxisLength = _heatMapGraph.PixelHeight - (int)yAxisOffset - (int)topOffset; const double axisThickness = 10; var axisPen = new Pen(Brushes.Black, axisThickness); var axisTickPen = new Pen(Brushes.Black, axisThickness / 2); DrawHeatMap(); var heatMapRect = new Rectangle { Fill = new ImageBrush(_heatMap) { Stretch = Stretch.Uniform }, Effect = _heatMapColourEffect }; var heatMapRectSize = new Size(xAxisLength, yAxisLength); heatMapRect.Measure(heatMapRectSize); heatMapRect.Arrange(new Rect(new Point(xAxisOffset + 5, topOffset), heatMapRectSize)); _heatMapGraph.Render(heatMapRect); var heatMapKeyWidth = xAxisLength; const int heatMapKeyHeight = 100; var heatMapKeyRect = new Rectangle { Fill = new ImageBrush(DrawHeatKey(heatMapKeyWidth, heatMapKeyHeight)), Effect = _heatMapColourEffect }; var heatMapKeySize = new Size(heatMapKeyWidth, heatMapKeyHeight); heatMapKeyRect.Measure(heatMapKeySize); heatMapKeyRect.Arrange(new Rect(new Point(xAxisOffset + 5, _heatMapGraph.PixelHeight - yAxisOffset + topOffset + 150), heatMapKeySize)); _heatMapGraph.Render(heatMapKeyRect); var drawingVisual = new DrawingVisual(); var textTypeFace = new Typeface(new FontFamily("Arial"), FontStyles.Normal, FontWeights.Normal, FontStretches.Normal); const double headerFontSize = 80d; const double fontSize = 40d; const int numberOfTicks = 10; var fontBrush = Brushes.Black; using (var context = drawingVisual.RenderOpen()) { //Y Axis context.DrawLine(axisPen, new Point(xAxisOffset, topOffset), new Point(xAxisOffset, topOffset + yAxisLength)); //X Axis context.DrawLine(axisPen, new Point(xAxisOffset - 5, topOffset + yAxisLength), new Point(xAxisOffset + xAxisLength + 5, topOffset + yAxisLength)); context.DrawText(new FormattedText(MinValue.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, textTypeFace, headerFontSize, fontBrush), new Point(xAxisOffset + 5, _heatMapGraph.PixelHeight - yAxisOffset + topOffset + 250)); context.DrawText(new FormattedText(MaxValue.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, textTypeFace, headerFontSize, fontBrush), new Point(xAxisOffset + 5 + xAxisLength, _heatMapGraph.PixelHeight - yAxisOffset + topOffset + 250)); context.DrawText(new FormattedText("Time", CultureInfo.InvariantCulture, FlowDirection.LeftToRight, textTypeFace, headerFontSize, fontBrush), new Point(xAxisOffset + (xAxisLength / 2), topOffset + yAxisLength + 60)); var dateDistance = (MaxTimestamp - MinTimestamp).Ticks / numberOfTicks; for (var i = 0; i < numberOfTicks; i++) { var date = MinTimestamp + new TimeSpan(i * dateDistance); var xValue = (1 - ((MaxTimestamp - date).TotalSeconds / (MaxTimestamp - MinTimestamp).TotalSeconds)) * xAxisLength + xAxisOffset; context.DrawLine(axisTickPen, new Point(xValue, topOffset + yAxisLength), new Point(xValue, topOffset + yAxisLength + 20)); context.DrawText(new FormattedText(date.ToString("yyyy/MM/dd HH:mm"), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, textTypeFace, fontSize, fontBrush), new Point(xValue, topOffset + yAxisLength + 10)); } context.PushTransform(new RotateTransform(90)); context.DrawText(new FormattedText("Depth", CultureInfo.InvariantCulture, FlowDirection.LeftToRight, textTypeFace, headerFontSize, fontBrush), new Point((topOffset + (yAxisLength / 2)), -headerFontSize * 2)); context.Pop(); if (_depths != null) { foreach (var depthYValue in _depths) { context.DrawText(new FormattedText(depthYValue.Depth.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, textTypeFace, fontSize, fontBrush), new Point(xAxisOffset - 100, topOffset + (depthYValue.YValue / _heatMap.PixelHeight) * yAxisLength)); context.DrawLine(axisTickPen, new Point(xAxisOffset - 25, topOffset + (depthYValue.YValue / _heatMap.PixelHeight) * yAxisLength + (axisTickPen.Thickness / 2)), new Point(xAxisOffset, topOffset + (depthYValue.YValue / _heatMap.PixelHeight) * yAxisLength + (axisTickPen.Thickness / 2))); } } } _heatMapGraph.Render(drawingVisual); }
private void SnapshotCurrentImage() { if (IsComicLoaded()) { _cacheManager.UseCurrentImageStream((stream, imageName, containerName) => { var fileName = containerName + " - " + imageName; if (!(Directory.Exists(SNAPSHOT_PATH))) { Directory.CreateDirectory(SNAPSHOT_PATH); } var shaderEffect = imageViewbox.Effect; // If no effect is applied, then save source image directly to snapshot folder // otherwise, use image with effect applied and save as jpeg to snapshot folder if (shaderEffect == null) { var filePath = IOPath.Combine(SNAPSHOT_PATH, fileName); // No shader effects are applied so write the source image stream directly to file using (var fileStream = File.OpenWrite(filePath)) { stream.CopyTo(fileStream); } } else { //Note: Effect must be compiled to PixelShader version 2.0 otherwise, the effect // will be ignored when RenderTargetBitmap() is used. Limitation of WPF. var imageSource = (BitmapSource)comicImage.Source; // Create a Rectangle shape, fill its background with the current comic image // and apply the same shader effect var rectangle = new System.Windows.Shapes.Rectangle(); rectangle.Fill = new ImageBrush(imageSource); rectangle.Effect = shaderEffect; // Resize the Rectangle to full image size var size = new Size(imageSource.PixelWidth, imageSource.PixelHeight); rectangle.Measure(size); rectangle.Arrange(new Rect(size)); //TODO: 96 is hardcoded for my monitor. Make it device dependent // or find a different method to save effect on image var renderTargetBitmap = new RenderTargetBitmap( imageSource.PixelWidth, imageSource.PixelHeight, 96, 96, PixelFormats.Pbgra32); renderTargetBitmap.Render(rectangle); var rerenderedFilename = IOPath.GetFileNameWithoutExtension(fileName); var encoder = new JpegBitmapEncoder { QualityLevel = 95 }; var bitmapFrame = BitmapFrame.Create(renderTargetBitmap); encoder.Frames.Add(bitmapFrame); var filePath = IOPath.Combine(SNAPSHOT_PATH, rerenderedFilename + ".jpeg"); using (var fileStream = File.OpenWrite(filePath)) { encoder.Save(fileStream); } } DisplayMessage(string.Format("Snapshot '{0}'", fileName)); }); } }
/// <summary> /// Helper method to create a 4:3 solid color image. /// </summary> /// <param name="brush">The brush to use to fill the image.</param> /// <returns>The created image.</returns> private static ImageSource CreateColorImage(Brush brush) { RenderTargetBitmap rtb = new RenderTargetBitmap(4, 3, 96, 96, System.Windows.Media.PixelFormats.Pbgra32); var rect = new System.Windows.Shapes.Rectangle { Width = 4, Height = 3, Fill = brush }; rect.Arrange(new System.Windows.Rect(0, 0, rect.Width, rect.Height)); rtb.Render(rect); return rtb; }