private void DisplayParameters(Bitmap img, ImageType type) { ImagePropertiesUi propertyObject = GetPropertyObject(type); float rawSize; using (var bh = new BitmapHelper(img)) { rawSize = bh.SizeBytes / 1024.0f / 1024.0f; } propertyObject.Resolution = img.Size; propertyObject.RawSize = rawSize; propertyObject.PixelFormat = img.PixelFormat; }
public void LoadImageLayers(List<Bitmap> imageList) { var layers = new List<Layer>(); foreach (Bitmap image in imageList) { using (var helper = new BitmapHelper(image)) { BackgroundStatitics.CommitImageMemory(helper.SizeBytes); } Rectangle region = AppModel.Instance.Layout.NewLayerMetrics(image.Size); layers.Add(new Picture(image, region, 0)); } AppModel.Instance.LayerManager.AddRange(layers); }
// ==================================================================== // Helpers to operate with .NET types // ==================================================================== public static void ImageInterpolate(Bitmap srcImg, Bitmap tarImg, Bitmap dstImg, float step) { StaticCheckFormat(PixelFormat.Format24bppRgb, srcImg, tarImg, dstImg); StaticCheckSameSize(srcImg, tarImg, dstImg); // Less work for caller: let C++ handle threading using (var ibSrc = new BitmapHelper(srcImg)) using (var ibTar = new BitmapHelper(tarImg)) using (var ibDest = new BitmapHelper(dstImg)) { unsafe { ImageProcessingWrapper.Blend24bgr_24bgr( ibSrc.Start, ibTar.Start, ibDest.Start, ibDest.SizeBytes, step); } } // More work for caller: let C# run more threads // TODO: How to mark here that C++ should not do MT in this case? /*unsafe { BitmapData resultData = resultImage.LockBits( new Rectangle(0, 0, resultImage.Width, resultImage.Height), ImageLockMode.ReadWrite, resultImage.PixelFormat); BitmapData src1Data = srcImage1.LockBits( new Rectangle(0, 0, srcImage1.Width, srcImage1.Height), ImageLockMode.ReadOnly, srcImage1.PixelFormat); BitmapData src2Data = srcImage2.LockBits( new Rectangle(0, 0, srcImage2.Width, srcImage2.Height), ImageLockMode.ReadOnly, srcImage2.PixelFormat); int heightInPixels = resultData.Height; uint stride = (uint)Math.Abs(resultData.Stride); Parallel.For(0, heightInPixels, y => { byte* currentLineSrc1 = (byte*)src1Data.Scan0 + (y * stride); byte* currentLineSrc2 = (byte*)src2Data.Scan0 + (y * stride); byte* currentLineResult = (byte*)resultData.Scan0 + (y * stride); ImageProcessingWrapper.Blend24bgr_24bgr( currentLineSrc1, currentLineSrc2, currentLineResult, stride, step); }); resultImage.UnlockBits(resultData); srcImage1.UnlockBits(src1Data); srcImage2.UnlockBits(src2Data); }*/ }
public static void ImageAlphaBlend(Bitmap srcImg, Bitmap tarImg, Bitmap dstImg) { StaticCheckFormat(PixelFormat.Format32bppArgb, srcImg, tarImg, dstImg); StaticCheckSameSize(srcImg, tarImg, dstImg); // Less work for caller: let C++ handle threading using (var ibSrc = new BitmapHelper(srcImg)) using (var ibTar = new BitmapHelper(tarImg)) using (var ibDest = new BitmapHelper(dstImg)) { unsafe { ImageProcessingWrapper.AlphaBlend32bgra_32bgra( ibSrc.Start, ibTar.Start, ibDest.Start, ibDest.SizeBytes); } } }
public static void ConvolutionFilter(Bitmap srcImg, Bitmap dstImg, float[] kernel) { StaticCheckFormat(PixelFormat.Format32bppArgb, srcImg, dstImg); StaticCheckSameSize(srcImg, dstImg); using (var ibSrc = new BitmapHelper(srcImg)) using (var ibDest = new BitmapHelper(dstImg)) { var stride = ibSrc.Stride; var size = ibSrc.SizeBytes; var kw = (uint)Math.Sqrt(kernel.GetLength(0)); var kh = (uint)kernel.Length / kw; unsafe { // TODO: Testing only - reference c code //SetImplementationLevel("ConvFilter_32bgra", 0); ImageProcessingWrapper.ConvFilter_32bgra( ibSrc.Start, ibDest.Start, size, stride, kernel, kw, kh); } } }
private unsafe void ScanlineRenderer(int y, Rectangle dirtyRegion, BitmapHelper frameData) { byte* currentScanLine = frameData.Start + (y * frameData.Stride); // TODO: If top-most layer covering the scanline is 100% opaque /*if (objectCollection.Count > 0) { Layer last = objectCollection.Last; if (last.Transparency == 100 && (ScanlineIntersects(y, last.Region))) { CompositeIfNeeded(y, dirtyRegion, currentScanLine, last, rasterizer); return; } }*/ // Do a Painter's algorithm iteration (back->front) on the layers for (int index = 0; index < objectCollection.Count; index++) { Layer layer = objectCollection[index]; CompositeIfNeeded(y, dirtyRegion, currentScanLine, layer); } }
private unsafe byte* LayerPixel(Rectangle layerRegion, BitmapHelper layerInfo, int y) { byte* src = (layerInfo.Start + // layer data start (y - layerRegion.Top) * layerInfo.Stride) + // image data row (layerRegion.Left < 0 ? layerInfo.PixelSize * Math.Abs(layerRegion.Left) : 0); // image data column return src; }
private unsafe byte* FrameBufferPixel(byte* currentScanLine, int leftOffset, BitmapHelper layerInfo) { byte* dst = currentScanLine + (leftOffset) * layerInfo.PixelSize; // frame scanline return dst; }
private uint DirtySize(int leftOffset, int rightOffset, BitmapHelper layerInfo) { uint dirtySizeBytes = (uint)((rightOffset - leftOffset) * layerInfo.PixelSize); // size of modified scanline region return dirtySizeBytes; }
public void UpdateFrame(SortedContainer<Layer> objectCollection, IRenderingPolicy renderPolicy) { // Clip the invalidated region to the size of the frame renderPolicy.ClipToFrame(frame.Size); // Refreh the invalidated frame/region profiler.ProfileClearFrame(() => { Color clearColor = Color.FromArgb(255, surfaceInfo.GraphicsBackground); using (SolidBrush clearBrush = new SolidBrush(clearColor)) { /*var localPolicy = renderPolicy as MinimalUpdate; if (localPolicy != null && localPolicy.OldRegion != default(Rectangle)) { _frameGraphics.FillRectangle(clearBrush, localPolicy.OldRegion); }*/ frameGraphics.FillRectangle(clearBrush, renderPolicy.DirtyRegion); } }); profiler.ProfileRasterizeObjects(() => { using (var frameInfo = new BitmapHelper(frame)) // lock framebuffer data using (var rasterizer = new RasterizerStage(objectCollection, surfaceInfo)) // rasterize all scene objects using (var compositor = new CompositionStage(objectCollection, rasterizer)) { // perform scene composition on needed regions compositor.Composite(renderPolicy, frameInfo); } }); // Draw the new completed frame/region on the visible area profiler.ProfileDrawFrame(() => { RefreshFrame(renderPolicy); }); // Notify interested clients with statistics after frame update if (graphicsUpdateCallback != null) graphicsUpdateCallback.BeginInvoke(profiler, null, null); }
public static void ImageOpacity(Bitmap srcImg, Bitmap dstImg, float step) { StaticCheckFormat(PixelFormat.Format32bppArgb, srcImg, dstImg, dstImg); StaticCheckSameSize(srcImg, srcImg, dstImg); // Less work for caller: let C++ handle threading using (var ibSrc = new BitmapHelper(srcImg)) using (var ibDest = new BitmapHelper(dstImg)) { unsafe { ImageProcessingWrapper.OpacityAdjust_32bgra( ibSrc.Start, ibDest.Start, ibDest.SizeBytes, step); } } }