public SoftwareBitmap GetBitmap() { SoftwareBitmap bitmap = null; //Needs to run in UI thread CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { bitmap = new SoftwareBitmap(BitmapPixelFormat.Bgra8, (int)dim.width, (int)dim.height); }).AsTask().Wait(); using (BitmapBuffer buffer = bitmap.LockBuffer(BitmapBufferAccessMode.Write)) using (var reference = buffer.CreateReference()) { unsafe { ((IMemoryBufferByteAccess)reference).GetBuffer(out var tempByteArray, out uint capacity); // Fill-in the BGRA plane BitmapPlaneDescription bufferLayout = buffer.GetPlaneDescription(0); for (int i = 0; i < bufferLayout.Width * bufferLayout.Height; i++) { tempByteArray[bufferLayout.StartIndex + (i * 4)] = data[(i * cpp) + 2]; tempByteArray[bufferLayout.StartIndex + (i * 4) + 1] = data[(i * cpp) + 1]; tempByteArray[bufferLayout.StartIndex + (i * 4) + 2] = data[(i * cpp)]; if (cpp == 4) { tempByteArray[bufferLayout.StartIndex + (i * 4) + 3] = data[(i * 4) + 3]; } else { tempByteArray[bufferLayout.StartIndex + (i * 4) + 3] = 255; } } } } return(bitmap); }
/// <summary> /// Draws a polyline anti-aliased. Add the first point also at the end of the array if the line should be closed. /// </summary> /// <param name="bmp">The WriteableBitmap.</param> /// <param name="points">The points of the polyline in x and y pairs, therefore the array is interpreted as (x1, y1, x2, y2, ..., xn, yn).</param> /// <param name="color">The color for the line.</param> public static void dbugDrawPolylineAa(this BitmapBuffer bmp, int[] points, int color) { using (BitmapContext context = bmp.GetBitmapContext()) { // Use refs for faster access (really important!) speeds up a lot! int w = context.Width; int h = context.Height; int x1 = points[0]; int y1 = points[1]; for (int i = 2; i < points.Length; i += 2) { //int x2 = points[i]; //int y2 = points[i + 1]; DrawLineAa(context, w, h, x1, y1, x1 += points[i], y1 += points[i + 1], //also update x1,y1 color); //x1 = x2; //y1 = y2; } } }
public Texture2d LoadTexture(BitmapBuffer bmp) { Texture2d ret = null; int id = GenTexture(); try { ret = new Texture2d(this, id, bmp.Width, bmp.Height); GL.BindTexture(TextureTarget.Texture2D, id); //picking a color order that matches doesnt seem to help, any. maybe my driver is accelerating it, or maybe it isnt a big deal. but its something to study on another day GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp.Width, bmp.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero); (this as IGL).LoadTextureData(ret, bmp); } catch { GL.DeleteTexture(id); throw; } //set default filtering.. its safest to do this always ret.SetFilterNearest(); return(ret); }
public Win32VtkRenderingSurface(IntPtr windowId, bool offscreen) { _imageBuffer = new BitmapBuffer(PixelFormat.Format32bppRgb); _overlayBuffer = new BitmapBuffer(PixelFormat.Format32bppArgb); _finalBuffer = new BackBuffer(); _vtkRenderer = new vtkRenderer(); _vtkRenderer.SetBackground(0.0f, 0.0f, 0.0f); _vtkRenderWindow = new vtkWin32OpenGLRenderWindow(); _vtkRenderWindow.OffScreenRenderingOn(); _vtkRenderWindow.DoubleBufferOff(); _vtkRenderWindow.EraseOn(); _vtkRenderWindow.SwapBuffersOff(); _vtkRenderWindow.SetDesiredUpdateRate(_dynamicFrameRate); _vtkRenderWindow.AddRenderer(_vtkRenderer); var delayTime = Math.Min(10000, Math.Max(100, Settings.Default.RendererRefinementDelayMs)); _dynamicFrameRate = Math.Min(1000, Math.Max(1, Settings.Default.RendererDynamicFps)); _dynamicRenderEventPublisher = !offscreen ? new DelayedEventPublisher((s, e) => Render(true, null), delayTime) : null; WindowID = windowId; }
void UpdateRenderFrame() { // Wrap updates in a GetContext call, to prevent invalidation and nested locking/unlocking during this block // NOTE: This is not strictly necessary for the SL version as this is a WPF feature, however we include it here for completeness and to show // a similar API to WPF //render! using (var bmplock = destBmp.Lock()) { BitmapBuffer wb = bmplock.GetWritableBitmap(); emitter.TargetBitmap = wb; emitter.ParticleBitmap = particleBmp; wb.Clear(Colors.Black); double elapsed = (DateTime.Now - lastUpdate).TotalSeconds; lastUpdate = DateTime.Now; emitter.Update(elapsed); // bmp.Blit(new Point(100, 150), circleBmp, new Rect(0, 0, 200, 200), Colors.Red, BlendMode.Additive); // bmp.Blit(new Point(160, 55), circleBmp, new Rect(0, 0, 200, 200), Color.FromArgb(255, 0, 255, 0), BlendMode.Additive); // bmp.Blit(new Point(220, 150), circleBmp, new Rect(0, 0, 200, 200), Colors.Blue, BlendMode.Additive); //double timeNow = _stopwatch.ElapsedMilliseconds; //double elapsedMilliseconds = timeNow - _lastTime; //_lowestFrameTime = Math.Min(_lowestFrameTime, elapsedMilliseconds); //// FpsCounter.Text = string.Format("FPS: {0:0.0} / Max: {1:0.0}", 1000.0 / elapsedMilliseconds, 1000.0 / _lowestFrameTime); //_lastTime = timeNow; // bmplock.WriteAndUnlock(); // g.Clear(System.Drawing.Color.White); g.DrawImage(destBmp, 0, 0); } }
public unsafe BitmapBuffer ResolveTexture2d(Texture2d tex) { //TODO - lazy create and cache resolving target in RT var target = new d3d9.Texture(dev, tex.IntWidth, tex.IntHeight, 1, d3d9.Usage.None, d3d9.Format.A8R8G8B8, d3d9.Pool.SystemMemory); var tw = tex.Opaque as TextureWrapper; dev.GetRenderTargetData(tw.Texture.GetSurfaceLevel(0), target.GetSurfaceLevel(0)); var dr = target.LockRectangle(0, LockFlags.ReadOnly); if (dr.Pitch != tex.IntWidth * 4) { throw new InvalidOperationException(); } int[] pixels = new int[tex.IntWidth * tex.IntHeight]; dr.Data.ReadRange(pixels, 0, tex.IntWidth * tex.IntHeight); var bb = new BitmapBuffer(tex.IntWidth, tex.IntHeight, pixels); target.UnlockRectangle(0); target.Dispose(); //buffer churn warning //TEMPORARY until flipping is sorted out bb.YFlip(); return(bb); }
public Texture2d LoadTexture(sd.Bitmap bitmap) { using var bmp = new BitmapBuffer(bitmap, new BitmapLoadOptions()); return((this as IGL).LoadTexture(bmp)); }
FilterProgram UpdateSourceInternal(JobInfo job) { if (job.chain_outsize.Width == 0 || job.chain_outsize.Height == 0) { //this has to be a NOP, because lots of stuff will malfunction on a 0-sized viewport return(null); } //no drawing actually happens. it's important not to begin drawing on a control if (!job.simulate && !job.offscreen) { GLManager.Activate(CR_GraphicsControl); } IVideoProvider videoProvider = job.videoProvider; bool simulate = job.simulate; Size chain_outsize = job.chain_outsize; //simulate = true; int vw = videoProvider.BufferWidth; int vh = videoProvider.BufferHeight; if (Global.Config.DispFixAspectRatio) { if (Global.Config.DispManagerAR == Config.EDispManagerAR.System) { vw = videoProvider.VirtualWidth; vh = videoProvider.VirtualHeight; } if (Global.Config.DispManagerAR == Config.EDispManagerAR.Custom) { vw = Global.Config.DispCustomUserARWidth; vh = Global.Config.DispCustomUserARHeight; } if (Global.Config.DispManagerAR == Config.EDispManagerAR.CustomRatio) { FixRatio(Global.Config.DispCustomUserARX, Global.Config.DispCustomUserARY, videoProvider.BufferWidth, videoProvider.BufferHeight, out vw, out vh); } } var padding = CalculateCompleteContentPadding(true, false); vw += padding.Horizontal; vh += padding.Vertical; int[] videoBuffer = videoProvider.GetVideoBuffer(); int bufferWidth = videoProvider.BufferWidth; int bufferHeight = videoProvider.BufferHeight; bool isGlTextureId = videoBuffer.Length == 1; BitmapBuffer bb = null; Texture2d videoTexture = null; if (!simulate) { if (isGlTextureId) { //FYI: this is a million years from happening on n64, since it's all geriatric non-FBO code //is it workable for saturn? videoTexture = GL.WrapGLTexture2d(new IntPtr(videoBuffer[0]), bufferWidth, bufferHeight); } else { //wrap the videoprovider data in a BitmapBuffer (no point to refactoring that many IVideoProviders) bb = new BitmapBuffer(bufferWidth, bufferHeight, videoBuffer); bb.DiscardAlpha(); //now, acquire the data sent from the videoProvider into a texture videoTexture = VideoTextureFrugalizer.Get(bb); //lets not use this. lets define BizwareGL to make clamp by default (TBD: check opengl) //GL.SetTextureWrapMode(videoTexture, true); } } //record the size of what we received, since lua and stuff is gonna want to draw onto it currEmuWidth = bufferWidth; currEmuHeight = bufferHeight; //build the default filter chain and set it up with services filters will need Size chain_insize = new Size(bufferWidth, bufferHeight); var filterProgram = BuildDefaultChain(chain_insize, chain_outsize, job.includeOSD); filterProgram.GuiRenderer = Renderer; filterProgram.GL = GL; //setup the source image filter EmuHawk.Filters.SourceImage fInput = filterProgram["input"] as EmuHawk.Filters.SourceImage; fInput.Texture = videoTexture; //setup the final presentation filter EmuHawk.Filters.FinalPresentation fPresent = filterProgram["presentation"] as EmuHawk.Filters.FinalPresentation; fPresent.VirtualTextureSize = new Size(vw, vh); fPresent.TextureSize = new Size(bufferWidth, bufferHeight); fPresent.BackgroundColor = videoProvider.BackgroundColor; fPresent.GuiRenderer = Renderer; fPresent.Flip = isGlTextureId; fPresent.Config_FixAspectRatio = Global.Config.DispFixAspectRatio; fPresent.Config_FixScaleInteger = Global.Config.DispFixScaleInteger; fPresent.Padding = ClientExtraPadding; fPresent.AutoPrescale = Global.Config.DispAutoPrescale; fPresent.GL = GL; filterProgram.Compile("default", chain_insize, chain_outsize, !job.offscreen); if (simulate) { } else { CurrentFilterProgram = filterProgram; UpdateSourceDrawingWork(job); } //cleanup: if (bb != null) { bb.Dispose(); } return(filterProgram); }
public BitmapBufferVideoProvider(BitmapBuffer bb) { this.bb = bb; }
/// <summary> /// Tests the led strip graphics. /// </summary> public static void TestLedStripGraphics() { BitmapBuffer pixels = null; try { using (var bitmap = new System.Drawing.Bitmap(Path.Combine(Runtime.EntryAssemblyDirectory, "fractal.jpg"))) { $"Loaded bitmap with format {bitmap.PixelFormat}".Info(); pixels = new BitmapBuffer(bitmap); $"Loaded Pixel Data: {pixels.Data.Length} bytes".Info(); } } catch (Exception ex) { $"Error Loading image: {ex.Message}".Error(); } var exitAnimation = false; var useDynamicBrightness = false; var frameRenderTimes = new Queue <int>(); var frameTimes = new Queue <int>(); var thread = new Thread(() => { var strip = new LedStripAPA102C(60 * 4, 1, 1000000); // 1 Mhz is sufficient for such a short strip (only 240 LEDs) var millisecondsPerFrame = 1000 / 25; var lastRenderTime = DateTime.UtcNow; var currentFrameNumber = 0; var currentBrightness = 0.8f; var currentRow = 0; var currentDirection = 1; while (!exitAnimation) { // Push pixels into the Frame Buffer strip.SetPixels(pixels, 0, currentRow, currentBrightness); // Move the current row slowly at FPS currentRow += currentDirection; if (currentRow >= pixels.ImageHeight) { currentRow = pixels.ImageHeight - 2; currentDirection = -1; } else if (currentRow <= 0) { currentRow = 1; currentDirection = 1; } if (useDynamicBrightness) { currentBrightness = 0.05f + (0.80f * (currentRow / (pixels.ImageHeight - 1f))); } // Stats and sleep time var delayMilliseconds = (int)DateTime.UtcNow.Subtract(lastRenderTime).TotalMilliseconds; frameRenderTimes.Enqueue(delayMilliseconds); delayMilliseconds = millisecondsPerFrame - delayMilliseconds; if (delayMilliseconds > 0 && exitAnimation == false) { Thread.Sleep(delayMilliseconds); } else { $"Lagging framerate: {delayMilliseconds} milliseconds".Info(); } frameTimes.Enqueue((int)DateTime.UtcNow.Subtract(lastRenderTime).TotalMilliseconds); lastRenderTime = DateTime.UtcNow; // Push the framebuffer to SPI strip.Render(); if (currentFrameNumber == int.MaxValue) { currentFrameNumber = 0; } else { currentFrameNumber++; } if (frameRenderTimes.Count >= 2048) { frameRenderTimes.Dequeue(); } if (frameTimes.Count >= 20148) { frameTimes.Dequeue(); } } strip.ClearPixels(); strip.Render(); var avg = frameRenderTimes.Average(); $"Frames: {currentFrameNumber + 1}, FPS: {Math.Round(1000f / frameTimes.Average(), 3)}, Strip Render: {Math.Round(avg, 3)} ms, Max FPS: {Math.Round(1000 / avg, 3)}" .Info(); strip.Render(); }); thread.Start(); Console.Write("Press any key to stop and clear"); Console.ReadKey(true); Console.WriteLine(); exitAnimation = true; }
public static double browser_draw(double browserIdDouble, double x, double y) { int browserId = (int)browserIdDouble; // this is so stupid, GML... if (browserId < 0 || browserId >= browsers.Count || browsers[browserId] == null) { return(0); } //Debug.WriteLine("Draw"); Browser browserObj = browsers[browserId]; if (browserObj.texture == null || browserObj.textureSize.Width != browserObj.browser.Size.Width || browserObj.textureSize.Height != browserObj.browser.Size.Height) { Debug.WriteLine("Recreate texture " + browserObj.browser.Size.Width + "x" + browserObj.browser.Size.Height); browserObj.textureSize = new Size(browserObj.browser.Size.Width, browserObj.browser.Size.Height); if (browserObj.texture != null) { browserObj.texture.Dispose(); } browserObj.texture = new Texture(device, browserObj.textureSize.Width, browserObj.textureSize.Height, 1, Usage.Dynamic, Format.A8R8G8B8, Pool.Default); } BitmapBuffer buffer = (browserObj.browser.RenderHandler as DefaultRenderHandler).BitmapBuffer; lock (buffer.BitmapLock) { if (buffer.Width == 0 || buffer.Height == 0 || buffer.Buffer.Length == 0) { Debug.WriteLine("No buffer!!!"); return(0); } if (browserObj.textureSize.Width != buffer.Width || browserObj.textureSize.Height != buffer.Height) { Debug.WriteLine("Invalid buffer size!!!"); return(0); } var rect = browserObj.texture.LockRectangle(0, LockFlags.None); unsafe { fixed(byte *buf = buffer.Buffer) { for (int yy = 0; yy < buffer.Height; yy++) { Buffer.MemoryCopy(buf + yy * buffer.Width * 4, (byte *)rect.DataPointer.ToPointer() + yy * rect.Pitch, (uint)(buffer.Width * 4), (uint)(buffer.Width * 4)); } } } browserObj.texture.UnlockRectangle(0); } if (browsers[browserId].sprite == null) { browsers[browserId].sprite = new Sprite(device); } browsers[browserId].sprite.Begin(); browsers[browserId].sprite.Draw(browsers[browserId].texture, new RawColorBGRA(255, 255, 255, 255), null, null, new RawVector3((float)x, (float)y, 0.0f)); browsers[browserId].sprite.End(); return(1); }
/// <summary> /// Sets a number of pixels from loaded pixel data directly into the frame buffer /// This is the fastest method to set a number of pixels. /// Call the Render Method to apply! /// </summary> /// <param name="pixels">The pixel data of a previously loaded bitmap.</param> /// <param name="sourceOffsetX">The x offset in the bitmap to start copying pixels from</param> /// <param name="sourceOffsetY">The row index (y) from which to take the pixel data</param> /// <param name="brightness">The brightness from 0.0 to 1.0. The underlying precision is from 0 to 31</param> /// <param name="targetOffset">The target offset where to start setting the pixels.</param> /// <param name="targetLength">The number of pixels to set. 0 or less means the entire LedCount</param> /// <exception cref="ArgumentOutOfRangeException">startX /// or /// y</exception> /// <exception cref="ArgumentNullException">bitmap</exception> public void SetPixels(BitmapBuffer pixels, int sourceOffsetX, int sourceOffsetY, float brightness = 1f, int targetOffset = 0, int targetLength = 0) { var brightnessByte = default(byte); { // Parameter validation if (pixels == null) { throw new ArgumentNullException(nameof(pixels)); } if (sourceOffsetX < 0 || sourceOffsetX > (pixels.ImageWidth - targetLength) - 1) { throw new ArgumentOutOfRangeException(nameof(sourceOffsetX)); } if (sourceOffsetY < 0 || sourceOffsetY >= pixels.ImageHeight) { throw new ArgumentOutOfRangeException(nameof(sourceOffsetY), $"{nameof(sourceOffsetY)} was '{sourceOffsetY}' but it must be between '0' and '{pixels.ImageHeight - 1}'"); } if (targetOffset < 0) { targetOffset = 0; } if (targetOffset > LedCount - 1) { throw new ArgumentOutOfRangeException(nameof(targetOffset)); } if (targetLength <= 0) { targetLength = LedCount; } if (targetOffset + targetLength > LedCount) { throw new ArgumentOutOfRangeException(nameof(targetLength)); } // Brightness Setting if (brightness < 0f) { brightness = 0f; } if (brightness > 1f) { brightness = 1f; } brightnessByte = (byte)(brightness * 31); brightnessByte = (byte)(brightnessByte | BrightnessSetMask); } // Offset settings var offsetB = ReverseRgb ? 1 : 3; var offsetG = 2; var offsetR = ReverseRgb ? 3 : 1; var offsetT = 0; // Pixel copying lock (SyncLock) { var bmpOffsetBase = pixels.GetPixelOffset(sourceOffsetX, sourceOffsetY); var bmpOffsetLimit = bmpOffsetBase + (targetLength * BitmapBuffer.BytesPerPixel); var setCount = 0; var frameBufferOffset = StartFrame.Length + (targetOffset * StartFrame.Length); for (var bmpOffset = bmpOffsetBase; bmpOffset < bmpOffsetLimit; bmpOffset += BitmapBuffer.BytesPerPixel) { FrameBuffer[frameBufferOffset + offsetT] = brightnessByte; FrameBuffer[frameBufferOffset + offsetR] = pixels.Data[bmpOffset + BitmapBuffer.ROffset]; // R FrameBuffer[frameBufferOffset + offsetG] = pixels.Data[bmpOffset + BitmapBuffer.GOffset]; // G FrameBuffer[frameBufferOffset + offsetB] = pixels.Data[bmpOffset + BitmapBuffer.BOffset]; // B frameBufferOffset += StartFrame.Length; setCount += 1; if (setCount >= targetLength) { break; } } } }
public unsafe override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode) { applyRect = IntersectRectangle(applyBitmap.Size, rect); if (applyRect.Height <= 0 || applyRect.Width <= 0) { return; } int blurRadius = GetFieldValueAsInt(FieldType.BLUR_RADIUS); double previewQuality = GetFieldValueAsDouble(FieldType.PREVIEW_QUALITY); // do nothing when nothing can be done! if (blurRadius < 1) { return; } using (BitmapBuffer bbbDest = new BitmapBuffer(applyBitmap, applyRect)) { bbbDest.Lock(); using (BitmapBuffer bbbSrc = new BitmapBuffer(applyBitmap, applyRect)) { bbbSrc.Lock(); Random rand = new Random(); int r = blurRadius; int[] w = CreateGaussianBlurRow(r); int wlen = w.Length; long[] waSums = new long[wlen]; long[] wcSums = new long[wlen]; long[] aSums = new long[wlen]; long[] bSums = new long[wlen]; long[] gSums = new long[wlen]; long[] rSums = new long[wlen]; for (int y = 0; y < applyRect.Height; ++y) { long waSum = 0; long wcSum = 0; long aSum = 0; long bSum = 0; long gSum = 0; long rSum = 0; for (int wx = 0; wx < wlen; ++wx) { int srcX = wx - r; waSums[wx] = 0; wcSums[wx] = 0; aSums[wx] = 0; bSums[wx] = 0; gSums[wx] = 0; rSums[wx] = 0; if (srcX >= 0 && srcX < bbbDest.Width) { for (int wy = 0; wy < wlen; ++wy) { int srcY = y + wy - r; if (srcY >= 0 && srcY < bbbDest.Height) { int[] colors = bbbSrc.GetColorArrayAt(srcX, srcY); int wp = w[wy]; waSums[wx] += wp; wp *= colors[0] + (colors[0] >> 7); wcSums[wx] += wp; wp >>= 8; aSums[wx] += wp * colors[0]; bSums[wx] += wp * colors[3]; gSums[wx] += wp * colors[2]; rSums[wx] += wp * colors[1]; } } int wwx = w[wx]; waSum += wwx * waSums[wx]; wcSum += wwx * wcSums[wx]; aSum += wwx * aSums[wx]; bSum += wwx * bSums[wx]; gSum += wwx * gSums[wx]; rSum += wwx * rSums[wx]; } } wcSum >>= 8; if (waSum == 0 || wcSum == 0) { SetColorAt(bbbDest, 0, y, new int[] { 0, 0, 0, 0 }); } else { int alpha = (int)(aSum / waSum); int blue = (int)(bSum / wcSum); int green = (int)(gSum / wcSum); int red = (int)(rSum / wcSum); SetColorAt(bbbDest, 0, y, new int[] { alpha, red, green, blue }); } for (int x = 1; x < applyRect.Width; ++x) { for (int i = 0; i < wlen - 1; ++i) { waSums[i] = waSums[i + 1]; wcSums[i] = wcSums[i + 1]; aSums[i] = aSums[i + 1]; bSums[i] = bSums[i + 1]; gSums[i] = gSums[i + 1]; rSums[i] = rSums[i + 1]; } waSum = 0; wcSum = 0; aSum = 0; bSum = 0; gSum = 0; rSum = 0; int wx; for (wx = 0; wx < wlen - 1; ++wx) { long wwx = (long)w[wx]; waSum += wwx * waSums[wx]; wcSum += wwx * wcSums[wx]; aSum += wwx * aSums[wx]; bSum += wwx * bSums[wx]; gSum += wwx * gSums[wx]; rSum += wwx * rSums[wx]; } wx = wlen - 1; waSums[wx] = 0; wcSums[wx] = 0; aSums[wx] = 0; bSums[wx] = 0; gSums[wx] = 0; rSums[wx] = 0; int srcX = x + wx - r; if (srcX >= 0 && srcX < applyRect.Width) { for (int wy = 0; wy < wlen; ++wy) { int srcY = y + wy - r; // only when in EDIT mode, ignore some pixels depending on preview quality if ((renderMode == RenderMode.EXPORT || rand.NextDouble() < previewQuality) && srcY >= 0 && srcY < applyRect.Height) { int[] colors = bbbSrc.GetColorArrayAt(srcX, srcY); int wp = w[wy]; waSums[wx] += wp; wp *= colors[0] + (colors[0] >> 7); wcSums[wx] += wp; wp >>= 8; aSums[wx] += wp * (long)colors[0]; bSums[wx] += wp * (long)colors[3]; gSums[wx] += wp * (long)colors[2]; rSums[wx] += wp * (long)colors[1]; } } int wr = w[wx]; waSum += (long)wr * waSums[wx]; wcSum += (long)wr * wcSums[wx]; aSum += (long)wr * aSums[wx]; bSum += (long)wr * bSums[wx]; gSum += (long)wr * gSums[wx]; rSum += (long)wr * rSums[wx]; } wcSum >>= 8; if (waSum == 0 || wcSum == 0) { SetColorAt(bbbDest, x, y, new int[] { 0, 0, 0, 0 }); } else { int alpha = (int)(aSum / waSum); int blue = (int)(bSum / wcSum); int green = (int)(gSum / wcSum); int red = (int)(rSum / wcSum); SetColorAt(bbbDest, x, y, new int[] { alpha, red, green, blue }); } } } } bbbDest.DrawTo(graphics, applyRect.Location); } }
/// <summary> /// A Fast Bresenham Type Algorithm For Drawing Ellipses http://homepage.smc.edu/kennedy_john/belipse.pdf /// Uses a different parameter representation than DrawEllipse(). /// </summary> /// <param name="bmp">The WriteableBitmap.</param> /// <param name="xc">The x-coordinate of the ellipses center.</param> /// <param name="yc">The y-coordinate of the ellipses center.</param> /// <param name="xr">The radius of the ellipse in x-direction.</param> /// <param name="yr">The radius of the ellipse in y-direction.</param> /// <param name="color">The color for the line.</param> public static unsafe void DrawEllipseCentered(this BitmapBuffer bmp, int xc, int yc, int xr, int yr, int color) { // Use refs for faster access (really important!) speeds up a lot! using (BitmapContext context = bmp.GetBitmapContext()) { int *pixels = context.Pixels._inf32Buffer; int w = context.Width; int h = context.Height; // Avoid endless loop if (xr < 1 || yr < 1) { return; } // Init vars int uh, lh, uy, ly, lx, rx; int x = xr; int y = 0; int xrSqTwo = (xr * xr) << 1; int yrSqTwo = (yr * yr) << 1; int xChg = yr * yr * (1 - (xr << 1)); int yChg = xr * xr; int err = 0; int xStopping = yrSqTwo * xr; int yStopping = 0; // Draw first set of points counter clockwise where tangent line slope > -1. while (xStopping >= yStopping) { // Draw 4 quadrant points at once uy = yc + y; // Upper half ly = yc - y; // Lower half if (uy < 0) { uy = 0; // Clip } if (uy >= h) { uy = h - 1; // ... } if (ly < 0) { ly = 0; } if (ly >= h) { ly = h - 1; } uh = uy * w; // Upper half lh = ly * w; // Lower half rx = xc + x; lx = xc - x; if (rx < 0) { rx = 0; // Clip } if (rx >= w) { rx = w - 1; // ... } if (lx < 0) { lx = 0; } if (lx >= w) { lx = w - 1; } pixels[rx + uh] = color; // Quadrant I (Actually an octant) pixels[lx + uh] = color; // Quadrant II pixels[lx + lh] = color; // Quadrant III pixels[rx + lh] = color; // Quadrant IV y++; yStopping += xrSqTwo; err += yChg; yChg += xrSqTwo; if ((xChg + (err << 1)) > 0) { x--; xStopping -= yrSqTwo; err += xChg; xChg += yrSqTwo; } } // ReInit vars x = 0; y = yr; uy = yc + y; // Upper half ly = yc - y; // Lower half if (uy < 0) { uy = 0; // Clip } if (uy >= h) { uy = h - 1; // ... } if (ly < 0) { ly = 0; } if (ly >= h) { ly = h - 1; } uh = uy * w; // Upper half lh = ly * w; // Lower half xChg = yr * yr; yChg = xr * xr * (1 - (yr << 1)); err = 0; xStopping = 0; yStopping = xrSqTwo * yr; // Draw second set of points clockwise where tangent line slope < -1. while (xStopping <= yStopping) { // Draw 4 quadrant points at once rx = xc + x; lx = xc - x; if (rx < 0) { rx = 0; // Clip } if (rx >= w) { rx = w - 1; // ... } if (lx < 0) { lx = 0; } if (lx >= w) { lx = w - 1; } pixels[rx + uh] = color; // Quadrant I (Actually an octant) pixels[lx + uh] = color; // Quadrant II pixels[lx + lh] = color; // Quadrant III pixels[rx + lh] = color; // Quadrant IV x++; xStopping += yrSqTwo; err += xChg; xChg += yrSqTwo; if ((yChg + (err << 1)) > 0) { y--; uy = yc + y; // Upper half ly = yc - y; // Lower half if (uy < 0) { uy = 0; // Clip } if (uy >= h) { uy = h - 1; // ... } if (ly < 0) { ly = 0; } if (ly >= h) { ly = h - 1; } uh = uy * w; // Upper half lh = ly * w; // Lower half yStopping -= xrSqTwo; err += yChg; yChg += xrSqTwo; } } } }
/// <summary> /// A Fast Bresenham Type Algorithm For Drawing Ellipses http://homepage.smc.edu/kennedy_john/belipse.pdf /// Uses a different parameter representation than DrawEllipse(). /// </summary> /// <param name="bmp">The WriteableBitmap.</param> /// <param name="xc">The x-coordinate of the ellipses center.</param> /// <param name="yc">The y-coordinate of the ellipses center.</param> /// <param name="xr">The radius of the ellipse in x-direction.</param> /// <param name="yr">The radius of the ellipse in y-direction.</param> /// <param name="color">The color for the line.</param> public static void DrawEllipseCentered(this BitmapBuffer bmp, int xc, int yc, int xr, int yr, ColorInt color) { bmp.DrawEllipseCentered(xc, yc, xr, yr, color.ToPreMultAlphaColor()); }
public void ReleaseSurface(BitmapBuffer surface) { lock (this) ReleasedSurfaces.Enqueue(surface); }
static async Task Main() { Console.WriteLine("Video Capture Test"); //await ListDevicesAndFormats(); //Console.ReadLine(); var mediaFrameReader = await StartVideoCapture().ConfigureAwait(false); if (mediaFrameReader != null) { // Open a Window to display the video feed from video capture device _form = new Form(); _form.AutoSize = true; _form.BackgroundImageLayout = ImageLayout.Center; _picBox = new PictureBox { Size = new Size(FRAME_WIDTH, FRAME_HEIGHT), Location = new Point(0, 0), Visible = true }; _form.Controls.Add(_picBox); bool taskRunning = false; SoftwareBitmap backBuffer = null; // Lambda handler for captured frames. mediaFrameReader.FrameArrived += async(MediaFrameReader sender, MediaFrameArrivedEventArgs e) => { if (taskRunning) { return; } taskRunning = true; var mediaFrameReference = sender.TryAcquireLatestFrame(); var videoMediaFrame = mediaFrameReference?.VideoMediaFrame; var softwareBitmap = videoMediaFrame?.SoftwareBitmap; if (softwareBitmap == null && videoMediaFrame != null) { var videoFrame = videoMediaFrame.GetVideoFrame(); softwareBitmap = await SoftwareBitmap.CreateCopyFromSurfaceAsync(videoFrame.Direct3DSurface); } if (softwareBitmap != null) { Console.WriteLine($"Software bitmap pixel fmt {softwareBitmap.BitmapPixelFormat}, alpha mode {softwareBitmap.BitmapAlphaMode}."); if (softwareBitmap.BitmapPixelFormat != Windows.Graphics.Imaging.BitmapPixelFormat.Bgra8 || softwareBitmap.BitmapAlphaMode != Windows.Graphics.Imaging.BitmapAlphaMode.Premultiplied) { softwareBitmap = SoftwareBitmap.Convert(softwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied); } int width = softwareBitmap.PixelWidth; int height = softwareBitmap.PixelHeight; Console.WriteLine($"Software bitmap frame size {width}x{height}."); // Swap the processed frame to _backBuffer and dispose of the unused image. softwareBitmap = Interlocked.Exchange(ref backBuffer, softwareBitmap); softwareBitmap?.Dispose(); _form.BeginInvoke(new Action(() => { if (_picBox.Width != width || _picBox.Height != height) { _picBox.Size = new Size(width, height); } using (BitmapBuffer buffer = backBuffer.LockBuffer(BitmapBufferAccessMode.Read)) { using (var reference = buffer.CreateReference()) { unsafe { byte *dataInBytes; uint capacity; reference.As <IMemoryBufferByteAccess>().GetBuffer(out dataInBytes, out capacity); Bitmap bmpImage = new Bitmap((int)width, (int)height, (int)(capacity / height), PixelFormat.Format32bppArgb, (IntPtr)dataInBytes); _picBox.Image = bmpImage; } } } })); } else { Console.WriteLine("null"); } taskRunning = false; }; Console.WriteLine("Starting media frame reader."); _ = Task.Run(async() => await mediaFrameReader.StartAsync()).ConfigureAwait(false); Console.WriteLine("Starting Windows Forms message loop."); Application.EnableVisualStyles(); Application.Run(_form); } else { Console.WriteLine("Could not acquire a media frame reader."); } }
/// <summary> /// Event handler for video frames for the local video capture device. /// </summary> private async void FrameArrivedHandler(MediaFrameReader sender, MediaFrameArrivedEventArgs e) { if (!_isClosed) { using (var frame = sender.TryAcquireLatestFrame()) { if (_isClosed || frame == null) { return; } var vmf = frame.VideoMediaFrame; var videoFrame = vmf.GetVideoFrame(); var sbmp = await SoftwareBitmap.CreateCopyFromSurfaceAsync(videoFrame.Direct3DSurface); if (sbmp == null) { logger.LogWarning("Failed to get bitmap from video frame reader."); } else { if (!_isClosed && OnVideoSourceEncodedSample != null) { lock (_vp8Encoder) { SoftwareBitmap nv12bmp = null; // If the bitmap is not in the required pixel format for the encoder convert it. if (_mediaFrameSource.CurrentFormat.Subtype != VIDEO_DESIRED_PIXEL_FORMAT) { nv12bmp = SoftwareBitmap.Convert(sbmp, BitmapPixelFormat.Nv12); } byte[] nv12Buffer = null; SoftwareBitmap inputBmp = nv12bmp ?? sbmp; using (BitmapBuffer buffer = inputBmp.LockBuffer(BitmapBufferAccessMode.Read)) { using (var reference = buffer.CreateReference()) { unsafe { byte *dataInBytes; uint capacity; ((IMemoryBufferByteAccess)reference).GetBuffer(out dataInBytes, out capacity); nv12Buffer = new byte[capacity]; Marshal.Copy((IntPtr)dataInBytes, nv12Buffer, 0, (int)capacity); } } } byte[] encodedBuffer = null; encodedBuffer = _vp8Encoder.Encode(nv12Buffer, _forceKeyFrame); if (encodedBuffer != null) { uint fps = (_fpsDenominator > 0 && _fpsNumerator > 0) ? _fpsNumerator / _fpsDenominator : DEFAULT_FRAMES_PER_SECOND; uint durationRtpTS = VIDEO_SAMPLING_RATE / fps; OnVideoSourceEncodedSample.Invoke(durationRtpTS, encodedBuffer); } if (_forceKeyFrame) { _forceKeyFrame = false; } nv12bmp?.Dispose(); } } sbmp.Dispose(); videoFrame.Dispose(); } } } }
public Texture2d Get(DisplaySurface ds) { using var bb = new BitmapBuffer(ds.PeekBitmap(), new BitmapLoadOptions()); return(Get(bb)); }
public unsafe int[] applyModification(ushort[] image, iPoint2D dim, iPoint2D offset, int colorDepth, ref SoftwareBitmap bitmap) { int[] value = new int[256]; using (BitmapBuffer buffer = bitmap.LockBuffer(BitmapBufferAccessMode.Write)) { using (var reference = buffer.CreateReference()) { BitmapPlaneDescription bufferLayout = buffer.GetPlaneDescription(0); ((IMemoryBufferByteAccess)reference).GetBuffer(out var temp, out uint capacity); maxValue = (uint)(1 << colorDepth); int shift = colorDepth - 8; if (!cameraWB) { mul = new float[4]; //Balance.calculateRGB((int)temperature, out mul[0], out mul[1], out mul[2]); mul[2] = (float)(255 / temperature); mul[0] = (float)(255.0 / tint); mul[1] = 1; } //generate the curve double[] xCurve = new double[5], yCurve = new double[5]; //mid point xCurve[2] = maxValue / 2; yCurve[2] = maxValue / 2; //shadow xCurve[0] = 0; yCurve[0] = shadow * (maxValue / (400)); //hightlight xCurve[4] = maxValue; yCurve[4] = maxValue - (hightlight * (maxValue / 400)); //contrast xCurve[1] = maxValue / 4; yCurve[1] = ((yCurve[0] + yCurve[2]) / 2) - (maxValue / 200); xCurve[3] = maxValue * 3 / 4; yCurve[3] = ((yCurve[2] + yCurve[4]) / 2) + (maxValue / 200); maxValue--; //interpolate with spline //double[] contrastCurve = Balance.contrast_curve(shadow, hightlight, 1 << colorDepth); double[] contrastCurve = Curve.cubicSpline(xCurve, yCurve); //Change the gamma/No more gammaneeded here, the raw should be transformed to neutral gamma before demos //double[] gammaCurve = Balance.gamma_curve(0.45, 4.5, 2, 8192 << 3); //gammacurve from camera //double[] gammaCurve = Balance.gamma_curve(camCurve[0] / 100, camCurve[1] / 10, 2, 8192 << 3); Parallel.For(offset.y, dim.y + offset.y, y => { int realY = y * dim.x * 3; int bufferY = y * dim.x * 4 + +bufferLayout.StartIndex; for (int x = offset.x; x < dim.x + offset.x; x++) { int realPix = realY + (3 * x); int bufferPix = bufferY + (4 * x); //get the RGB value double red = image[realPix], green = image[realPix + 1], blue = image[realPix + 2]; //convert to linear rgb (not needed, the raw should be in linear already) /*Balance.sRGBToRGB(ref red, maxValue - 1); * Balance.sRGBToRGB(ref green, maxValue - 1); * Balance.sRGBToRGB(ref blue, maxValue - 1);*/ //scale according to the white balance red *= mul[0]; green *= mul[1]; blue *= mul[2]; //clip Luminance.Clip(ref red, ref green, ref blue, maxValue); double h = 0, s = 0, l = 0; //transform to HSL value Color.rgbToHsl(red, green, blue, maxValue, ref h, ref s, ref l); //change brightness from curve //add saturation l = contrastCurve[(uint)(l * maxValue)] / maxValue; s *= saturation; s += vibrance; l *= exposure; l += brightness / 100; //change back to RGB Color.hslToRgb(h, s, l, maxValue, ref red, ref green, ref blue); //Luminance.Exposure(ref red, ref green, ref blue, exposure); //Luminance.Brightness(ref red, ref green, ref blue, brightness); //Balance.scaleGamma(ref red, ref green, ref blue, gamma, maxValue); Luminance.Contraste(ref red, ref green, ref blue, maxValue, contrast); //clip Luminance.Clip(ref red, ref green, ref blue, maxValue); temp[bufferPix] = (byte)((int)blue >> shift); temp[bufferPix + 1] = (byte)((int)green >> shift); temp[bufferPix + 2] = (byte)((int)red >> shift); Interlocked.Increment(ref value[(((int)red >> shift) + ((int)green >> shift) + ((int)blue >> shift)) / 3]); //set transparency to 255 else image will be blank temp[bufferPix + 3] = 255; //change gamma from curve /* * image[i * 3] = (ushort)gammaCurve[(int)red]; * image[(i * 3) + 1] = (ushort)gammaCurve[(int)green]; * image[(i * 3) + 2] = (ushort)gammaCurve[(int)blue];*/ } }); } } return(value); }
FilterProgram UpdateSourceInternal(JobInfo job) { _glManager.Activate(CR_GraphicsControl); IVideoProvider videoProvider = job.videoProvider; bool simulate = job.simulate; Size chain_outsize = job.chain_outsize; int vw = videoProvider.BufferWidth; int vh = videoProvider.BufferHeight; if (Global.Config.DispFixAspectRatio) { if (Global.Config.DispManagerAR == Config.EDispManagerAR.System) { vw = videoProvider.VirtualWidth; vh = videoProvider.VirtualHeight; } if (Global.Config.DispManagerAR == Config.EDispManagerAR.Custom) { vw = Global.Config.DispCustomUserARWidth; vh = Global.Config.DispCustomUserARHeight; } } int[] videoBuffer = videoProvider.GetVideoBuffer(); int bufferWidth = videoProvider.BufferWidth; int bufferHeight = videoProvider.BufferHeight; bool isGlTextureId = videoBuffer.Length == 1; //TODO - need to do some work here for GDI+ to repair gl texture ID importing BitmapBuffer bb = null; Texture2d videoTexture = null; if (!simulate) { if (isGlTextureId) { videoTexture = GL.WrapGLTexture2d(new IntPtr(videoBuffer[0]), bufferWidth, bufferHeight); } else { //wrap the videoprovider data in a BitmapBuffer (no point to refactoring that many IVideoProviders) bb = new BitmapBuffer(bufferWidth, bufferHeight, videoBuffer); //now, acquire the data sent from the videoProvider into a texture videoTexture = VideoTextureFrugalizer.Get(bb); GL.SetTextureWrapMode(videoTexture, true); } //TEST (to be removed once we have an actual example of bring in a texture ID from opengl emu core): //if (!isGlTextureId) //{ // videoBuffer = new int[1] { videoTexture.Id.ToInt32() }; // goto TESTEROO; //} } //record the size of what we received, since lua and stuff is gonna want to draw onto it currEmuWidth = bufferWidth; currEmuHeight = bufferHeight; //build the default filter chain and set it up with services filters will need Size chain_insize = new Size(bufferWidth, bufferHeight); var filterProgram = BuildDefaultChain(chain_insize, chain_outsize, job.includeOSD); filterProgram.GuiRenderer = Renderer; filterProgram.GL = GL; //setup the source image filter BizHawk.Client.EmuHawk.Filters.SourceImage fInput = filterProgram["input"] as BizHawk.Client.EmuHawk.Filters.SourceImage; fInput.Texture = videoTexture; //setup the final presentation filter BizHawk.Client.EmuHawk.Filters.FinalPresentation fPresent = filterProgram["presentation"] as BizHawk.Client.EmuHawk.Filters.FinalPresentation; fPresent.VirtualTextureSize = new Size(vw, vh); fPresent.TextureSize = new Size(bufferWidth, bufferHeight); fPresent.BackgroundColor = videoProvider.BackgroundColor; fPresent.GuiRenderer = Renderer; fPresent.GL = GL; filterProgram.Compile("default", chain_insize, chain_outsize, !job.offscreen); if (simulate) { } else { CurrentFilterProgram = filterProgram; UpdateSourceDrawingWork(job); } //cleanup: if (bb != null) { bb.Dispose(); } return(filterProgram); }
public void LoadTextureData(Texture2d tex, BitmapBuffer bmp) { var tw = tex.Opaque as GDIPTextureWrapper; bmp.ToSysdrawingBitmap(tw.SDBitmap); }
private void btnExport_Click(object sender, EventArgs e) { if (mFrameInfos.Count == 0) { return; } int width, height; using (var bmp = new Bitmap(mFrameInfos[0].pngPath)) { width = bmp.Width; height = bmp.Height; } var sfd = new SaveFileDialog { FileName = Path.ChangeExtension(mSynclessConfigFile, ".avi") }; sfd.InitialDirectory = Path.GetDirectoryName(sfd.FileName); if (sfd.ShowDialog() == DialogResult.Cancel) { return; } using (var avw = new AviWriter()) { avw.SetAudioParameters(44100, 2, 16); // hacky avw.SetMovieParameters(60, 1); // hacky avw.SetVideoParameters(width, height); var token = avw.AcquireVideoCodecToken(this); avw.SetVideoCodecToken(token); avw.OpenFile(sfd.FileName); foreach (var fi in mFrameInfos) { using (var bb = new BitmapBuffer(fi.pngPath, new BitmapLoadOptions())) { var bbvp = new BitmapBufferVideoProvider(bb); avw.AddFrame(bbvp); } // offset = 44 dec var wavBytes = File.ReadAllBytes(fi.wavPath); var ms = new MemoryStream(wavBytes) { Position = 44 }; var br = new BinaryReader(ms); var sampledata = new List <short>(); while (br.BaseStream.Position != br.BaseStream.Length) { sampledata.Add(br.ReadInt16()); } avw.AddSamples(sampledata.ToArray()); } avw.CloseFile(); } }
private void DrawFillDemo(BitmapBuffer writeableBmp) { // Wrap updates in a GetContext call, to prevent invalidation and nested locking/unlocking during this block using (writeableBmp.GetBitmapContext()) { // Init some size vars int w = writeableBmp.PixelWidth - 2; int h = writeableBmp.PixelHeight - 2; int w2 = w >> 1; int h2 = h >> 1; int w4 = w2 >> 1; int h4 = h2 >> 1; int w8 = w4 >> 1; int h8 = h4 >> 1; // Clear writeableBmp.Clear(); // Add circles const float startTimeFixed = 1; const float endTimeFixed = startTimeFixed + timeStep; const float startTimeRandom = 3; const float endTimeCurve = 9.7f; const int intervalRandom = 2; const int maxCircles = 30; // Spread fixed position and color circles if (time > startTimeFixed && time < endTimeFixed) { unchecked { circles.Add(new Circle { X = w8, Y = h8, Radius = 10f, Velocity = 1, Color = (int)0xFFC88717 }); circles.Add(new Circle { X = w8, Y = h - h8, Radius = 10f, Velocity = 1, Color = (int)0xFFFB522B }); circles.Add(new Circle { X = w - w8, Y = h8, Radius = 10f, Velocity = 1, Color = (int)0xFFDB6126 }); circles.Add(new Circle { X = w - w8, Y = h - h8, Radius = 10f, Velocity = 1, Color = (int)0xFFFFCE25 }); } } // Spread random position and color circles if (time > startTimeRandom && (int)time % intervalRandom == 0) { unchecked { circles.Add(new Circle { X = rand.Next(w), Y = rand.Next(h), Radius = 1f, Velocity = rand.Next(1, 5), Color = rand.Next((int)0xFFFF0000, (int)0xFFFFFFFF), }); } } // Render and update circles foreach (var circle in circles) { var r = (int)circle.Radius; writeableBmp.FillEllipseCentered(circle.X, circle.Y, r, r, circle.Color); circle.Update(); } if (circles.Count > maxCircles) { circles.RemoveAt(0); } // Fill closed Cardinal Spline curve if (time < endTimeCurve) { var p = new int[] { w4, h2, w2, h2 + h4, w2 + w4, h2, w2, h4, }; writeableBmp.FillCurveClosed(p, (float)Math.Sin(time) * 7, Colors.Black); } // Update time time += timeStep; // Invalidates on exit of Using block } }
/// <summary> /// Draws a polyline. Add the first point also at the end of the array if the line should be closed. /// </summary> /// <param name="bmp">The WriteableBitmap.</param> /// <param name="points">The points of the polyline in x and y pairs, therefore the array is interpreted as (x1, y1, x2, y2, ..., xn, yn).</param> /// <param name="color">The color for the line.</param> public static void dbugDrawPolylineAa(this BitmapBuffer bmp, int[] points, ColorInt color) { bmp.dbugDrawPolylineAa(points, color.ToPreMultAlphaColor()); }
/// <summary> /// Draws the different types of shapes. /// </summary> private void DrawStaticShapes(BitmapBuffer writeableBmp) { // HideShapeCountText(); // Wrap updates in a GetContext call, to prevent invalidation and nested locking/unlocking during this block using (writeableBmp.GetBitmapContext()) { // Init some size vars int w = writeableBmp.PixelWidth; int h = writeableBmp.PixelHeight; int w3 = w / 3; int h3 = h / 3; int w6 = w3 >> 1; int h6 = h3 >> 1; int w12 = w6 >> 1; int h12 = h6 >> 1; // Clear writeableBmp.Clear(); // Fill closed concave polygon var p = new int[] { w12 >> 1, h12, w6, h3 - (h12 >> 1), w3 - (w12 >> 1), h12, w6 + w12, h12, w6, h6 + h12, w12, h12, w12 >> 1, h12, }; writeableBmp.FillPolygonsEvenOdd(new[] { p }, GetRandomColor()); // Fill closed convex polygon p = new int[] { w3 + w6, h12 >> 1, w3 + w6 + w12, h12, w3 + w6 + w12, h6 + h12, w3 + w6, h6 + h12 + (h12 >> 1), w3 + w12, h6 + h12, w3 + w12, h12, w3 + w6, h12 >> 1, }; writeableBmp.FillPolygon(p, GetRandomColor()); // Fill Triangle + Quad writeableBmp.FillTriangle(2 * w3 + w6, h12 >> 1, 2 * w3 + w6 + w12, h6 + h12, 2 * w3 + w12, h6 + h12, GetRandomColor()); writeableBmp.FillQuad(w6, h3 + (h12 >> 1), w6 + w12, h3 + h6, w6, h3 + h6 + h12 + (h12 >> 1), w12, h3 + h6, GetRandomColor()); // Fill Ellipses writeableBmp.FillEllipse(rand.Next(w3, w3 + w6), rand.Next(h3, h3 + h6), rand.Next(w3 + w6, 2 * w3), rand.Next(h3 + h6, 2 * h3), GetRandomColor()); writeableBmp.FillEllipseCentered(2 * w3 + w6, h3 + h6, w12, h12, GetRandomColor()); // Fill closed Cardinal Spline curve p = new int[] { w12 >> 1, 2 * h3 + h12, w6, h - (h12 >> 1), w3 - (w12 >> 1), 2 * h3 + h12, w6 + w12, 2 * h3 + h12, w6, 2 * h3 + (h12 >> 1), w12, 2 * h3 + h12, }; writeableBmp.FillCurveClosed(p, 0.5f, GetRandomColor()); // Fill closed Beziér curve p = new int[] { w3 + w12, 2 * h3 + h6 + h12, w3 + w6 + (w12 >> 1), 2 * h3, w3 + w6 + w12 + (w12 >> 1), 2 * h3, w3 + w6 + w12, 2 * h3 + h6 + h12, }; writeableBmp.FillBeziers(p, GetRandomColor()); // Fill Rectangle writeableBmp.FillRectangle(rand.Next(2 * w3, 2 * w3 + w6), rand.Next(2 * h3, 2 * h3 + h6), rand.Next(2 * w3 + w6, w), rand.Next(2 * h3 + h6, h), GetRandomColor()); // Fill another rectangle with alpha blending writeableBmp.FillRectangle(rand.Next(2 * w3, 2 * w3 + w6), rand.Next(2 * h3, 2 * h3 + h6), rand.Next(2 * w3 + w6, w), rand.Next(2 * h3 + h6, h), GetRandomColor(), true); BitmapBufferEx.ColorInt black = BitmapBufferEx.ColorInt.FromArgb(255, 0, 0, 0); // Draw Grid writeableBmp.DrawLine(0, h3, w, h3, Colors.Black); writeableBmp.DrawLine(0, 2 * h3, w, 2 * h3, Colors.Black); writeableBmp.DrawLine(w3, 0, w3, h, Colors.Black); writeableBmp.DrawLine(2 * w3, 0, 2 * w3, h, Colors.Black); // Invalidates on exit of Using block } }
unsafe public static byte[] GetCroppedBitmap(SoftwareBitmap inputBitmap, uint startPointX, uint startPointY, uint width, uint height) { int bigger; if (width >= height) { bigger = (int)width; } else { bigger = (int)height; } // なぜか0が入れられることがある?けど無視したら動いてるからヨシ! if (bigger == 0) { return(new byte[0]); } SoftwareBitmap softwareBitmap = new SoftwareBitmap(BitmapPixelFormat.Bgra8, bigger, bigger, BitmapAlphaMode.Premultiplied); using (BitmapBuffer buffer = softwareBitmap.LockBuffer(BitmapBufferAccessMode.Write)) using (BitmapBuffer inputBuffer = inputBitmap.LockBuffer(BitmapBufferAccessMode.Write)) { using (var reference = buffer.CreateReference()) using (var inputReference = inputBuffer.CreateReference()) { byte *dataInBytes; uint capacity; ((IMemoryBufferByteAccess)reference).GetBuffer(out dataInBytes, out capacity); byte *inputDataInBytes; uint inputCapacity; ((IMemoryBufferByteAccess)inputReference).GetBuffer(out inputDataInBytes, out inputCapacity); BitmapPlaneDescription bufferLayout = buffer.GetPlaneDescription(0); BitmapPlaneDescription inputBufferLayout = inputBuffer.GetPlaneDescription(0); int h = bufferLayout.Height; for (int i = 0; i < bufferLayout.Height; i++) { for (int j = 0; j < bufferLayout.Width; j++) { byte valueB; byte valueG; byte valueR; byte valueA; if ((h - height) / 2 < i && (h + height) / 2 > i) { valueB = inputDataInBytes[inputBufferLayout.StartIndex + inputBufferLayout.Stride * (startPointY + i - (h - height) / 2) + 4 * (startPointX + j) + 0]; valueG = inputDataInBytes[inputBufferLayout.StartIndex + inputBufferLayout.Stride * (startPointY + i - (h - height) / 2) + 4 * (startPointX + j) + 1]; valueR = inputDataInBytes[inputBufferLayout.StartIndex + inputBufferLayout.Stride * (startPointY + i - (h - height) / 2) + 4 * (startPointX + j) + 2]; valueA = inputDataInBytes[inputBufferLayout.StartIndex + inputBufferLayout.Stride * (startPointY + i - (h - height) / 2) + 4 * (startPointX + j) + 3]; if (((double)valueR * 0.2126 + (double)valueG * 0.7152 + (double)valueB * 0.0772) / 255 > 0.5) { valueB = (byte)255; valueG = (byte)255; valueR = (byte)255; valueA = 0; } else { valueB = 0; valueG = 0; valueR = 0; valueA = 0; } } else { valueB = 0; valueG = 0; valueR = 0; valueA = 0; } dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 0] = valueB; dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 1] = valueG; dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 2] = valueR; dataInBytes[bufferLayout.StartIndex + bufferLayout.Stride * i + 4 * j + 3] = valueA; } } byte[] data = new byte[capacity]; Marshal.Copy((IntPtr)dataInBytes, data, 0, (int)capacity); return(data); } } }
public void Dispose() { _bb?.Dispose(); _bb = null; }
public Texture2d LoadTexture(Stream stream) { using var bmp = new BitmapBuffer(stream, new BitmapLoadOptions()); return((this as IGL).LoadTexture(bmp)); }
/// <summary> /// Draws the different types of shapes. /// </summary> private void DrawStaticShapes(BitmapBuffer writeableBmp) { // Wrap updates in a GetContext call, to prevent invalidation and nested locking/unlocking during this block using (writeableBmp.GetBitmapContext()) { // Init some size vars int w = writeableBmp.PixelWidth - 2; int h = writeableBmp.PixelHeight - 2; int w3rd = w / 3; int h3rd = h / 3; int w6th = w3rd >> 1; int h6th = h3rd >> 1; // Clear writeableBmp.Clear(); // Draw some points for (int i = 0; i < 200; i++) { writeableBmp.SetPixel(rand.Next(w3rd), rand.Next(h3rd), GetRandomColor()); } // Draw Standard shapes writeableBmp.DrawLine(rand.Next(w3rd, w3rd * 2), rand.Next(h3rd), rand.Next(w3rd, w3rd * 2), rand.Next(h3rd), GetRandomColor()); writeableBmp.DrawTriangle(rand.Next(w3rd * 2, w - w6th), rand.Next(h6th), rand.Next(w3rd * 2, w), rand.Next(h6th, h3rd), rand.Next(w - w6th, w), rand.Next(h3rd), GetRandomColor()); writeableBmp.DrawQuad(rand.Next(0, w6th), rand.Next(h3rd, h3rd + h6th), rand.Next(w6th, w3rd), rand.Next(h3rd, h3rd + h6th), rand.Next(w6th, w3rd), rand.Next(h3rd + h6th, 2 * h3rd), rand.Next(0, w6th), rand.Next(h3rd + h6th, 2 * h3rd), GetRandomColor()); writeableBmp.DrawRectangle(rand.Next(w3rd, w3rd + w6th), rand.Next(h3rd, h3rd + h6th), rand.Next(w3rd + w6th, w3rd * 2), rand.Next(h3rd + h6th, 2 * h3rd), GetRandomColor()); // Random polyline int[] p = new int[rand.Next(7, 10) * 2]; for (int j = 0; j < p.Length; j += 2) { p[j] = rand.Next(w3rd * 2, w); p[j + 1] = rand.Next(h3rd, 2 * h3rd); } writeableBmp.DrawPolyline(p, GetRandomColor()); // Random closed polyline p = new int[rand.Next(6, 9) * 2]; for (int j = 0; j < p.Length - 2; j += 2) { p[j] = rand.Next(w3rd); p[j + 1] = rand.Next(2 * h3rd, h); } p[p.Length - 2] = p[0]; p[p.Length - 1] = p[1]; writeableBmp.DrawPolyline(p, GetRandomColor()); // Ellipses writeableBmp.DrawEllipse(rand.Next(w3rd, w3rd + w6th), rand.Next(h3rd * 2, h - h6th), rand.Next(w3rd + w6th, w3rd * 2), rand.Next(h - h6th, h), GetRandomColor()); writeableBmp.DrawEllipseCentered(w - w6th, h - h6th, w6th >> 1, h6th >> 1, GetRandomColor()); // Draw Grid writeableBmp.DrawLine(0, h3rd, w, h3rd, Colors.Black); writeableBmp.DrawLine(0, 2 * h3rd, w, 2 * h3rd, Colors.Black); writeableBmp.DrawLine(w3rd, 0, w3rd, h, Colors.Black); writeableBmp.DrawLine(2 * w3rd, 0, 2 * w3rd, h, Colors.Black); // Invalidates on exit of using block } }