/// <summary> /// Renders the target bitmap. /// </summary> /// <param name="bitmapData">The bitmap data.</param> private void RenderTargetBitmap(BitmapDataBuffer bitmapData) { try { // Signal an update on the rendering surface TargetBitmap?.AddDirtyRect(bitmapData.UpdateRect); TargetBitmap?.Unlock(); } catch (Exception ex) { this.LogError(Aspects.VideoRenderer, $"{nameof(VideoRenderer)}.{nameof(RenderTargetBitmap)}", ex); } }
/// <summary> /// Renders the target bitmap. /// </summary> /// <param name="bitmapData">The bitmap data.</param> /// <param name="clockPosition">The clock position.</param> private void RenderTargetBitmap(BitmapDataBuffer bitmapData, TimeSpan clockPosition) { try { // Signal an update on the rendering surface TargetBitmap?.AddDirtyRect(bitmapData.UpdateRect); TargetBitmap?.Unlock(); } catch (Exception ex) { MediaElement?.MediaCore?.Log( MediaLogMessageType.Error, $"{nameof(VideoRenderer)} {ex.GetType()}: {ex.Message}. Stack Trace:\r\n{ex.StackTrace}"); } }
/// <summary> /// Creates a new resized WriteableBitmap. /// </summary> /// <param name="bmp">The WriteableBitmap.</param> /// <param name="width">The new desired width.</param> /// <param name="height">The new desired height.</param> /// <param name="interpolation">The interpolation method that should be used.</param> /// <returns>A new WriteableBitmap that is a resized version of the input.</returns> public static WriteableBitmap Resize(this WriteableBitmap bmp, int width, int height, Interpolation interpolation) { // Init vars int ws = bmp.PixelWidth; int hs = bmp.PixelHeight; #if SILVERLIGHT var ps = bmp.Pixels; var result = new WriteableBitmap(width, height); var pd = result.Pixels; #else bmp.Lock(); var result = new WriteableBitmap(width, height, 96.0, 96.0, PixelFormats.Bgra32, null); result.Lock(); unsafe { var ps = (int*) bmp.BackBuffer; var pd = (int*) result.BackBuffer; #endif float xs = (float) ws/width; float ys = (float) hs/height; float fracx, fracy, ifracx, ifracy, sx, sy, l0, l1; int c, x0, x1, y0, y1; byte c1a, c1r, c1g, c1b, c2a, c2r, c2g, c2b, c3a, c3r, c3g, c3b, c4a, c4r, c4g, c4b; byte a = 0, r = 0, g = 0, b = 0; // Nearest Neighbor if (interpolation == Interpolation.NearestNeighbor) { int srcIdx = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { sx = x*xs; sy = y*ys; x0 = (int) sx; y0 = (int) sy; pd[srcIdx++] = ps[y0*ws + x0]; } } } // Bilinear else if (interpolation == Interpolation.Bilinear) { int srcIdx = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { sx = x*xs; sy = y*ys; x0 = (int) sx; y0 = (int) sy; // Calculate coordinates of the 4 interpolation points fracx = sx - x0; fracy = sy - y0; ifracx = 1f - fracx; ifracy = 1f - fracy; x1 = x0 + 1; if (x1 >= ws) x1 = x0; y1 = y0 + 1; if (y1 >= hs) y1 = y0; // Read source color c = ps[y0*ws + x0]; c1a = (byte) (c >> 24); c1r = (byte) (c >> 16); c1g = (byte) (c >> 8); c1b = (byte) (c); c = ps[y0*ws + x1]; c2a = (byte) (c >> 24); c2r = (byte) (c >> 16); c2g = (byte) (c >> 8); c2b = (byte) (c); c = ps[y1*ws + x0]; c3a = (byte) (c >> 24); c3r = (byte) (c >> 16); c3g = (byte) (c >> 8); c3b = (byte) (c); c = ps[y1*ws + x1]; c4a = (byte) (c >> 24); c4r = (byte) (c >> 16); c4g = (byte) (c >> 8); c4b = (byte) (c); // Calculate colors // Alpha l0 = ifracx*c1a + fracx*c2a; l1 = ifracx*c3a + fracx*c4a; a = (byte) (ifracy*l0 + fracy*l1); if (a > 0) { // Red l0 = ifracx*c1r*c1a + fracx*c2r*c2a; l1 = ifracx*c3r*c3a + fracx*c4r*c4a; r = (byte) ((ifracy*l0 + fracy*l1)/a); // Green l0 = ifracx*c1g*c1a + fracx*c2g*c2a; l1 = ifracx*c3g*c3a + fracx*c4g*c4a; g = (byte) ((ifracy*l0 + fracy*l1)/a); // Blue l0 = ifracx*c1b*c1a + fracx*c2b*c2a; l1 = ifracx*c3b*c3a + fracx*c4b*c4a; b = (byte) ((ifracy*l0 + fracy*l1)/a); } // Write destination pd[srcIdx++] = (a << 24) | (r << 16) | (g << 8) | b; } } } #if !SILVERLIGHT } result.AddDirtyRect(new Int32Rect(0, 0, width, height)); result.Unlock(); bmp.Unlock(); #endif return result; }
public unsafe BitmapSource GetBitmapSource(int width, int height, float dpix, float dpiy, int rotation, RenderType type, bool rotateLandscapePages, bool convertToLetter, int maxSize) { WriteableBitmap write; int nLength = 0; IntPtr? data = _Api.GetBitmapData(this.m_pNativeObject, out width, out height, dpix, dpiy, rotation, (int)type, rotateLandscapePages, convertToLetter, out nLength, maxSize); if (data == null || data == IntPtr.Zero) { throw new Exception("Unable to render pdf page to bitmap!"); } if (type == RenderType.RGB) { const int depth = 24; int bmpstride = ((width * depth + 31) & ~31) >> 3; write = new WriteableBitmap(width, height, (double)dpix, (double)dpiy, PixelFormats.Bgr24, null); Int32Rect rect = new Int32Rect(0, 0, width, height); write.Lock(); byte *ptrSrc = (byte *)data; byte *ptrDest = (byte *)write.BackBuffer; for (int y = 0; y < height; y++) { byte *pl = ptrDest; byte *sl = ptrSrc; for (int x = 0; x < width; x++) { //Swap these here instead of in MuPDF because most pdf images will be rgb or cmyk. //Since we are going through the pixels one by one anyway swap here to save a conversion from rgb to bgr. pl[2] = sl[0]; //b-r pl[1] = sl[1]; //g-g pl[0] = sl[2]; //r-b //pl[3] = sl[3]; //alpha pl += 3; sl += 4; } ptrDest += bmpstride; ptrSrc += width * 4; } write.AddDirtyRect(rect); write.Unlock(); } else if (type == RenderType.Grayscale) { const int depth = 8;//(n * 8) int bmpstride = ((width * depth + 31) & ~31) >> 3; write = new WriteableBitmap(width, height, (double)dpix, (double)dpiy, PixelFormats.Gray8, BitmapPalettes.Gray256); Int32Rect rect = new Int32Rect(0, 0, width, height); write.Lock(); byte *ptrSrc = (byte *)data; byte *ptrDest = (byte *)write.BackBuffer; for (int y = 0; y < height; y++) { byte *pl = ptrDest; byte *sl = ptrSrc; for (int x = 0; x < width; x++) { pl[0] = sl[0]; //g //pl[1] = sl[1]; //alpha pl += 1; sl += 2; } ptrDest += bmpstride; ptrSrc += width * 2; } write.AddDirtyRect(rect); write.Unlock(); } else//RenderType.Monochrome { write = new WriteableBitmap(width, height, (double)dpix, (double)dpiy, PixelFormats.BlackWhite, BitmapPalettes.BlackAndWhite); Int32Rect rect = new Int32Rect(0, 0, width, height); write.Lock(); byte *ptrSrc = (byte *)data; byte *ptrDest = (byte *)write.BackBuffer; for (int i = 0; i < nLength; i++) { ptrDest[i] = ptrSrc[i]; } write.AddDirtyRect(rect); write.Unlock(); } _Api.FreeRenderedPage(this.m_pNativeObject);//Free unmanaged array if (write.CanFreeze) { write.Freeze(); } return(write); }
public void InvalidateImageSource() { _imgBmp?.Lock(); _imgBmp?.AddDirtyRect(new Int32Rect(0, 0, _imgBmp.PixelWidth, _imgBmp.PixelHeight)); _imgBmp?.Unlock(); }
/// <summary> /// Paints on a pbgra32 WriteableBitmap with a stylized airbrush /// </summary> /// <param name="bmp">The bitmap to modify</param> /// <param name="from">The starting point of the stroke</param> /// <param name="to">The end point of the stroke</param> /// <param name="color">The color of the stroke</param> /// <param name="size">The size of the stroke</param> public static unsafe void Airbrush(WriteableBitmap bmp, Point from, Point to, Color color, int size) { Random r = new Random(); if (bmp == null) { return; } bmp.Lock(); // Create a line segment representation LineSegment segment = new LineSegment(from, to); // Get a bounding box for the painted area BoundingBox bitmapbounds = new BoundingBox(); BoundingBox segmentbounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); segmentbounds.AddPoint((int)from.X, (int)from.Y, size + AirbrushDotRadius); segmentbounds.AddPoint((int)to.X, (int)to.Y, size + AirbrushDotRadius); segmentbounds.Clip(bitmapbounds); UInt32 *start = (UInt32 *)bmp.BackBuffer.ToPointer(); int stride = bmp.BackBufferStride / sizeof(UInt32); // Move from 'from' to 'to' along timestep intervals, with one dot painted per interval for (int i = 0; i < AirbrushDots; i++) { int x, y; segment.Interpolate(i, AirbrushDots, out x, out y); int dist = r.Next() % size; double angle = r.NextDouble() * 2 * Math.PI; double dx = Math.Cos(angle) * dist; double dy = Math.Sqrt(dist * dist - dx * dx); if (angle > Math.PI) { dy = -dy; } int bx = x + (int)dx; int by = y + (int)dy; BoundingBox dotbounds = new BoundingBox(); dotbounds.AddPoint(bx, by, AirbrushDotRadius); dotbounds.Clip(bitmapbounds); for (int k = dotbounds.Top, row = 0; k < dotbounds.Bottom; k++, y++, row++) { for (int j = dotbounds.Left, col = 0; j < dotbounds.Right; j++, col++) { WriteAlphaBlended(start + stride * k + j, Color.FromArgb(AirbrushDotKernel[row][col], color.R, color.G, color.B)); } } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }
public unsafe static BitmapSource RobertsCrossFilter(this BitmapSource source, double[,] matrixX, double[,] matrixY) { int width = source.PixelWidth; int height = source.PixelHeight; var bitmap = new WriteableBitmap(source); int filterOffset = (matrixX.GetLength(1) - 1) / 2; bitmap.Lock(); var backBuffer = (byte *)bitmap.BackBuffer.ToPointer(); for (int y = 0; y < height - filterOffset; y++) { var row = backBuffer + (y * bitmap.BackBufferStride); for (int x = 0; x < width - filterOffset; x++) { var redX = 0.0; var greenX = 0.0; var blueX = 0.0; var redY = 0.0; var greenY = 0.0; var blueY = 0.0; for (int filterY = -filterOffset; filterY <= filterOffset; filterY++) { for (int filterX = -filterOffset; filterX <= filterOffset; filterX++) { redX += (byte)(row[x * PIXEL_SIZE] * matrixX[filterY + filterOffset, filterX + filterOffset]); greenX += (byte)(row[x * PIXEL_SIZE + 1] * matrixX[filterY + filterOffset, filterX + filterOffset]); blueX += (byte)(row[x * PIXEL_SIZE + 2] * matrixX[filterY + filterOffset, filterX + filterOffset]); } } for (int filterY = -filterOffset; filterY <= filterOffset; filterY++) { for (int filterX = -filterOffset; filterX <= filterOffset; filterX++) { redY += (byte)(row[x * PIXEL_SIZE] * matrixX[filterY + filterOffset, filterX + filterOffset]); greenY += (byte)(row[x * PIXEL_SIZE + 1] * matrixX[filterY + filterOffset, filterX + filterOffset]); blueY += (byte)(row[x * PIXEL_SIZE + 2] * matrixX[filterY + filterOffset, filterX + filterOffset]); } } var red = Math.Sqrt((redX * redX) + (redY * redY)); var green = Math.Sqrt((greenX * greenX) + (greenY * greenY)); var blue = Math.Sqrt((blueX * blueX) + (blueY * blueY)); red = red > 255 ? 255 : red < 0 ? 0 : red; green = green > 255 ? 255 : green < 0 ? 0 : green; blue = blue > 255 ? 255 : blue < 0 ? 0 : blue; row[x * PIXEL_SIZE] = (byte)red; row[x * PIXEL_SIZE + 1] = (byte)green; row[x * PIXEL_SIZE + 2] = (byte)blue; } } bitmap.AddDirtyRect(new System.Windows.Int32Rect(0, 0, width, height)); bitmap.Unlock(); return(bitmap); }
/// <summary> /// Draw rectangle with given color. /// </summary> /// <param name="wBitmap">Must not be null, or pixel width, pixel height equal to zero</param> /// <param name="rectangle">The rectangle.</param> /// <param name="color">The color.</param> /// <exception>Exception should be expect with null writeablebitmap or pixel width, height equal to zero.</exception> /// <remarks></remarks> internal static void FillRectangle(this WriteableBitmap wBitmap, Int32Rect rectangle, Color color) { if (!(wBitmap.Format == PixelFormats.Pbgra32 || wBitmap.Format == PixelFormats.Gray8)) { return; } byte[] col = ConvertColor(wBitmap.Format, color); //Currently only support two PixelFormat. int sizeOfColor = wBitmap.Format == PixelFormats.Pbgra32 ? 4 : 1; int pixelW = wBitmap.Format == PixelFormats.Gray8 ? wBitmap.BackBufferStride : wBitmap.PixelWidth; int pixelH = wBitmap.PixelHeight; if (rectangle.X >= pixelW || rectangle.Y >= pixelH || rectangle.X + rectangle.Width - 1 < 0 || rectangle.Y + rectangle.Height - 1 < 0) { return; } if (rectangle.X < 0) { rectangle.X = 0; } if (rectangle.Y < 0) { rectangle.Y = 0; } if (rectangle.X + rectangle.Width >= pixelW) { rectangle.Width = pixelW - rectangle.X; } if (rectangle.Y + rectangle.Height >= pixelH) { rectangle.Height = pixelH - rectangle.Y; } wBitmap.Lock(); unsafe { var pixels = (byte *)wBitmap.BackBuffer; int startPoint = rectangle.Y * pixelW + rectangle.X; int endBoundry = startPoint + rectangle.Width; int srcOffsetBytes = startPoint * sizeOfColor; int length = col.Length; //Draw first dot color. for (int index = 0; index < length; index++) { *(pixels + srcOffsetBytes + index) = col[index]; } int pixelIndex = startPoint + 1; int blockPixels = 1; //Use first pixel color at (x, y) offset to draw first line. while (pixelIndex < endBoundry) { CopyUnmanagedMemory(pixels, srcOffsetBytes, pixels, pixelIndex * sizeOfColor, blockPixels * sizeOfColor); pixelIndex += blockPixels; blockPixels = Math.Min(2 * blockPixels, endBoundry - pixelIndex); } int bottomLeft = (rectangle.Y + rectangle.Height - 1) * pixelW + rectangle.X; //Use first line of pixel to fill up rest of rectangle. for (pixelIndex = startPoint + pixelW; pixelIndex <= bottomLeft; pixelIndex += pixelW) { CopyUnmanagedMemory(pixels, srcOffsetBytes, pixels, pixelIndex * sizeOfColor, rectangle.Width * sizeOfColor); } } wBitmap.AddDirtyRect(rectangle); wBitmap.Unlock(); }
/// <summary> /// Paints on a pbgra32 WriteableBitmap like a paintbrush /// </summary> /// <param name="bmp">The bitmap to modify</param> /// <param name="from">The starting point of the stroke</param> /// <param name="to">The end point of the stroke</param> /// <param name="previous">The point prior to the 'from' point, or null</param> /// <param name="color">The color of the brush</param> /// <param name="size">The stroke size</param> public static unsafe void Brush(WriteableBitmap bmp, Point from, Point to, Point?previous, Color color, int size) { if (bmp == null) { return; } bmp.Lock(); // Intermediate storage of the square of the size int sizesize = size * size; uint flatcolor = (uint)((int)color.A << 24) + (uint)((int)color.R << 16) + (uint)((int)color.G << 8) + color.B; // Create a line segment representation to compare distance to LineSegment linesegment = new LineSegment(from, to); // Get a bounding box for the line segment BoundingBox bitmapbounds = new BoundingBox(); BoundingBox segmentbounds = new BoundingBox(); bitmapbounds.AddPoint(0, 0, 0); bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0); segmentbounds.AddPoint((int)from.X, (int)from.Y, size); segmentbounds.AddPoint((int)to.X, (int)to.Y, size); segmentbounds.Clip(bitmapbounds); // Get a pointer to the back buffer (we use an int pointer here, since we can safely assume a 32-bit pixel format) UInt32 *start = (UInt32 *)bmp.BackBuffer.ToPointer(); // Move the starting pixel to the x offset start += segmentbounds.Left; if (previous.HasValue) { LineSegment previoussegment = new LineSegment(previous.Value, from); // Loop through the relevant portion of the image and figure out which pixels need to be erased for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++) { UInt32 *pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y; for (int x = segmentbounds.Left; x < segmentbounds.Right; x++) { if (linesegment.DistanceSquared(x, y) <= sizesize && previoussegment.DistanceSquared(x, y) > sizesize) { if (color.A == 255) { *pixel = flatcolor; } else { WriteAlphaBlended(pixel, color); } } // Move to the next pixel pixel++; } } } else { // Loop through the relevant portion of the image and figure out which pixels need to be erased for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++) { UInt32 *pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y; for (int x = segmentbounds.Left; x < segmentbounds.Right; x++) { if (linesegment.DistanceSquared(x, y) <= sizesize) { if (color.A == 255) { *pixel = flatcolor; } else { WriteAlphaBlended(pixel, color); } } // Move to the next pixel pixel++; } } } bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height)); bmp.Unlock(); }
private static void Reader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e) { bitmap = new WriteableBitmap(colorWidth, colorHeight, 96.0, 96.0, PixelFormats.Bgra32, null); // Calculate the WriteableBitmap back buffer size bitmapBackBufferSize = (uint)((bitmap.BackBufferStride * (bitmap.PixelHeight - 1)) + (bitmap.PixelWidth * bytesPerPixel)); int depthWidth = 0; int depthHeight = 0; DepthFrame depthFrame = null; ColorFrame colorFrame = null; BodyIndexFrame bodyIndexFrame = null; bool isBitmapLocked = false; MultiSourceFrame multiSourceFrame = e.FrameReference.AcquireFrame(); // If the Frame has expired by the time we process this event, return. if (multiSourceFrame == null) { return; } // We use a try/finally to ensure that we clean up before we exit the function. // This includes calling Dispose on any Frame objects that we may have and unlocking the bitmap back buffer. try { depthFrame = multiSourceFrame.DepthFrameReference.AcquireFrame(); colorFrame = multiSourceFrame.ColorFrameReference.AcquireFrame(); bodyIndexFrame = multiSourceFrame.BodyIndexFrameReference.AcquireFrame(); // If any frame has expired by the time we process this event, return. // The "finally" statement will Dispose any that are not null. if ((depthFrame == null) || (colorFrame == null) || (bodyIndexFrame == null)) { return; } // Process Depth FrameDescription depthFrameDescription = depthFrame.FrameDescription; depthWidth = depthFrameDescription.Width; depthHeight = depthFrameDescription.Height; // Access the depth frame data directly via LockImageBuffer to avoid making a copy using (KinectBuffer depthFrameData = depthFrame.LockImageBuffer()) { coordinateMapper.MapColorFrameToDepthSpaceUsingIntPtr( depthFrameData.UnderlyingBuffer, depthFrameData.Size, colorMappedToDepthPoints); } // We're done with the DepthFrame depthFrame.Dispose(); depthFrame = null; // Process Color Trace.WriteLine("\n\n\n\n BEFORE LOCK \n\n\n\n"); // Lock the bitmap for writing bitmap.Lock(); Trace.WriteLine("\n\n\n\n LOCK!!!! \n\n\n\n"); colorFrame.CopyConvertedFrameDataToIntPtr(bitmap.BackBuffer, bitmapBackBufferSize, ColorImageFormat.Bgra); // We're done with the ColorFrame colorFrame.Dispose(); colorFrame = null; // We'll access the body index data directly to avoid a copy using (KinectBuffer bodyIndexData = bodyIndexFrame.LockImageBuffer()) { unsafe { byte *bodyIndexDataPointer = (byte *)bodyIndexData.UnderlyingBuffer; int colorMappedToDepthPointCount = colorMappedToDepthPoints.Length; fixed(DepthSpacePoint *colorMappedToDepthPointsPointer = colorMappedToDepthPoints) { // Treat the color data as 4-byte pixels uint *bitmapPixelsPointer = (uint *)bitmap.BackBuffer; // Loop over each row and column of the color image // Zero out any pixels that don't correspond to a body index for (int colorIndex = 0; colorIndex < colorMappedToDepthPointCount; ++colorIndex) { float colorMappedToDepthX = colorMappedToDepthPointsPointer[colorIndex].X; float colorMappedToDepthY = colorMappedToDepthPointsPointer[colorIndex].Y; // The sentinel value is -inf, -inf, meaning that no depth pixel corresponds to this color pixel. if (!float.IsNegativeInfinity(colorMappedToDepthX) && !float.IsNegativeInfinity(colorMappedToDepthY)) { // Make sure the depth pixel maps to a valid point in color space int depthX = (int)(colorMappedToDepthX + 0.5f); int depthY = (int)(colorMappedToDepthY + 0.5f); // If the point is not valid, there is no body index there. if ((depthX >= 0) && (depthX < depthWidth) && (depthY >= 0) && (depthY < depthHeight)) { int depthIndex = (depthY * depthWidth) + depthX; // If we are tracking a body for the current pixel, do not zero out the pixel if (bodyIndexDataPointer[depthIndex] != 0xff) { continue; } } } bitmapPixelsPointer[colorIndex] = 0; } } bitmap.AddDirtyRect(new System.Windows.Int32Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight)); } } } finally { if (isBitmapLocked) { bitmap.Unlock(); var w = bitmap.PixelWidth; var h = bitmap.PixelHeight; var stride = w * ((bitmap.Format.BitsPerPixel + 7) / 8); var bitmapData = new byte[h * stride]; bitmap.CopyPixels(bitmapData, stride, 0); //greenScreenFrameData } if (depthFrame != null) { depthFrame.Dispose(); } if (colorFrame != null) { colorFrame.Dispose(); } if (bodyIndexFrame != null) { bodyIndexFrame.Dispose(); } } }
/// <summary> /// Draws a cubic Beziér spline defined by start, end and two control points. /// </summary> /// <param name="bmp">The WriteableBitmap.</param> /// <param name="x1">The x-coordinate of the start point.</param> /// <param name="y1">The y-coordinate of the start point.</param> /// <param name="cx1">The x-coordinate of the 1st control point.</param> /// <param name="cy1">The y-coordinate of the 1st control point.</param> /// <param name="cx2">The x-coordinate of the 2nd control point.</param> /// <param name="cy2">The y-coordinate of the 2nd control point.</param> /// <param name="x2">The x-coordinate of the end point.</param> /// <param name="y2">The y-coordinate of the end point.</param> /// <param name="color">The color.</param> public static void DrawBezier(this WriteableBitmap bmp, int x1, int y1, int cx1, int cy1, int cx2, int cy2, int x2, int y2, int color) { // Determine distances between controls points (bounding rect) to find the optimal stepsize int minX = Math.Min(x1, Math.Min(cx1, Math.Min(cx2, x2))); int minY = Math.Min(y1, Math.Min(cy1, Math.Min(cy2, y2))); int maxX = Math.Max(x1, Math.Max(cx1, Math.Max(cx2, x2))); int maxY = Math.Max(y1, Math.Max(cy1, Math.Max(cy2, y2))); // Get slope int lenx = maxX - minX; int len = maxY - minY; if (lenx > len) { len = lenx; } // Prevent divison by zero if (len != 0) { // Use refs for faster access (really important!) speeds up a lot! int w = bmp.PixelWidth; int h = bmp.PixelHeight; #if SILVERLIGHT int[] pixels = bmp.Pixels; #else bmp.Lock(); IntPtr pixels = bmp.BackBuffer; #endif // Init vars float step = StepFactor / len; int tx1 = x1; int ty1 = y1; int tx2, ty2; // Interpolate for (float t = step; t <= 1; t += step) { float tSq = t * t; float t1 = 1 - t; float t1Sq = t1 * t1; tx2 = (int)(t1 * t1Sq * x1 + 3 * t * t1Sq * cx1 + 3 * t1 * tSq * cx2 + t * tSq * x2); ty2 = (int)(t1 * t1Sq * y1 + 3 * t * t1Sq * cy1 + 3 * t1 * tSq * cy2 + t * tSq * y2); // Draw line DrawLine(pixels, w, h, tx1, ty1, tx2, ty2, color); tx1 = tx2; ty1 = ty2; } // Prevent rounding gap DrawLine(pixels, w, h, tx1, ty1, x2, y2, color); #if !SILVERLIGHT bmp.AddDirtyRect(new Int32Rect(0, 0, bmp.PixelWidth, bmp.PixelHeight)); bmp.Unlock(); #endif } }
public static void Main(string[] args) { Console.WriteLine(""); if (args.Length < 2) { usage(); } mapObj map = new mapObj(args[0]); Console.WriteLine("# Map layers " + map.numlayers + "; Map name = " + map.name); for (int i = 0; i < map.numlayers; i++) { Console.WriteLine("Layer [" + i + "] name: " + map.getLayer(i).name); } try { WriteableBitmap mapImage = new WriteableBitmap(map.width, map.height, 96, 96, PixelFormats.Bgr32, null); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); using (imageObj image = map.draw()) { // Reserve the back buffer for updates. mapImage.Lock(); try { if (image.getRawPixels(mapImage.BackBuffer) == (int)MS_RETURN_VALUE.MS_FAILURE) { Console.WriteLine("Unable to get image contents"); } // Specify the area of the bitmap that changed. mapImage.AddDirtyRect(new Int32Rect(0, 0, map.width, map.height)); } finally { // Release the back buffer and make it available for display. mapImage.Unlock(); } Console.WriteLine("Rendering time: " + stopwatch.ElapsedMilliseconds + "ms"); // Save the bitmap into a file. using (FileStream stream = new FileStream(args[1], FileMode.Create)) { PngBitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(mapImage)); encoder.Save(stream); } } } catch (Exception ex) { Console.WriteLine("\nMessage ---\n{0}", ex.Message); Console.WriteLine( "\nHelpLink ---\n{0}", ex.HelpLink); Console.WriteLine("\nSource ---\n{0}", ex.Source); Console.WriteLine( "\nStackTrace ---\n{0}", ex.StackTrace); Console.WriteLine( "\nTargetSite ---\n{0}", ex.TargetSite); } }
public void AddDirtyRect(Int32Rect dirtyRect) { source.AddDirtyRect(dirtyRect); }
public MainWindow() { InitializeComponent(); ptr = (int)bitmap.BackBuffer; bitmap.Lock(); unsafe { int index = width * (height - 1) * 4 + ptr; int last = width * height * 4 + ptr; for (; index < last; index += 4) { *((int *)index) = yellow; } } bitmap.AddDirtyRect(rect); bitmap.Unlock(); imageControl.Source = bitmap; DispatcherTimer timer = new DispatcherTimer(); timer.Interval = new TimeSpan(0, 0, 1); timer.Tick += Timer_Tick; timer.Start(); t = new Thread(() => { while (true) { int i, j, color; int last = (width * (height - 1) - gher + 1) * 4 + ptr; unsafe { for (i = wind * 4 + ptr; i < last; i += 4) { color = *((int *)(i + width * 4)); if (random.Next(100) < flame) { color = NextColor(color); } *((int *)(i + (random.Next(gher) - wind) * 4)) = color; } for (int k = 0; k < cursorX.Count; k++) { for (i = cursorX[k] - 10; i < cursorX[k] + 10; i++) { if (i >= 0 && i < width) { for (j = cursorY[k] - 10; j < cursorY[k] + 10; j++) { if (j >= 0 && j < height && Math.Pow(i - cursorX[k], 2) + Math.Pow(j - cursorY[k], 2) <= 100) { *((int *)((j * width + i) * 4 + ptr)) = yellow; } } } } } if (cursorX.Count > 1) { cursorX.RemoveRange(0, cursorX.Count - 1); cursorY.RemoveRange(0, cursorY.Count - 1); } } framesShown++; Dispatcher.BeginInvoke(new Action(() => { bitmap.Lock(); bitmap.AddDirtyRect(rect); bitmap.Unlock(); })); } }); t.Start(); }