public static ImageBuffer CreateScaledImage(ImageBuffer unscaledSourceImage, int width, int height) { ImageBuffer destImage = new ImageBuffer(width, height, 32, unscaledSourceImage.GetRecieveBlender()); // If the source image is more than twice as big as our dest image. while (unscaledSourceImage.Width > destImage.Width * 2) { // The image sampler we use is a 2x2 filter so we need to scale by a max of 1/2 if we want to get good results. // So we scale as many times as we need to get the Image to be the right size. // If this were going to be a non-uniform scale we could do the x and y separately to get better results. ImageBuffer halfImage = new ImageBuffer(unscaledSourceImage.Width / 2, unscaledSourceImage.Height / 2, 32, unscaledSourceImage.GetRecieveBlender()); halfImage.NewGraphics2D().Render(unscaledSourceImage, 0, 0, 0, halfImage.Width / (double)unscaledSourceImage.Width, halfImage.Height / (double)unscaledSourceImage.Height); unscaledSourceImage = halfImage; } Graphics2D renderGraphics = destImage.NewGraphics2D(); renderGraphics.ImageRenderQuality = Graphics2D.TransformQuality.Best; renderGraphics.Render(unscaledSourceImage, 0, 0, 0, destImage.Width / (double)unscaledSourceImage.Width, destImage.Height / (double)unscaledSourceImage.Height); destImage.MarkImageChanged(); return destImage; }
public void CopyNoramlBufferToImage(ImageBuffer destImage, RectangleInt viewport) { if (destImage.BitDepth != 32) { throw new Exception("We can only render to 32 bit dest at the moment."); } Byte[] destBuffer = destImage.GetBuffer(); viewport.Bottom = Math.Max(0, Math.Min(destImage.Height, viewport.Bottom)); viewport.Top = Math.Max(0, Math.Min(destImage.Height, viewport.Top)); #if MULTI_THREAD System.Threading.Tasks.Parallel.For(viewport.Bottom, viewport.Height, y => // #else for (int y = viewport.Bottom; y < viewport.Height; y++) #endif { for (int x = viewport.Left; x < viewport.Right; x++) { int bufferOffset = destImage.GetBufferOffsetY(y); // we don't need to set this if we are anti-aliased int totalOffset = bufferOffset + x * 4; destBuffer[totalOffset++] = (byte)((normalBuffer[x][y].x + 1) * 128); destBuffer[totalOffset++] = (byte)((normalBuffer[x][y].y + 1) * 128); ; destBuffer[totalOffset++] = (byte)((normalBuffer[x][y].z + 1) * 128); ; destBuffer[totalOffset] = 255; } } #if MULTI_THREAD ); #endif destImage.MarkImageChanged(); }
public void ProcessImage(ImageBuffer distortedImage, ImageBuffer rectifideImage) { if (distortedImage.BitDepth != 32 || rectifideImage.BitDepth != 32) { throw new ArgumentException("Both inputs must be 32 bit."); } if (distortedImage.Width != width || distortedImage.Height != height || rectifideImage.Width != width || rectifideImage.Height != height) { throw new ArgumentException("Both inputs must be the right size."); } byte[] distortedBuffer = distortedImage.GetBuffer(); byte[] rectifideBuffer = rectifideImage.GetBuffer(); if (DoBilinearFilter) { for (int i = 0; i < bilinearDistortedToRectifideOffsetTable.Length / 4; i++) { int rectifedBufferIndex = i * 4; int pixelOffset = bilinearDistortedToRectifideOffsetTable[i * 4 + 0] * 4; int weight = bilinearWeightTable[i * 4 + 0]; int red = distortedBuffer[pixelOffset + 0] * weight; int green = distortedBuffer[pixelOffset + 1] * weight; int blue = distortedBuffer[pixelOffset + 2] * weight; pixelOffset = bilinearDistortedToRectifideOffsetTable[i * 4 + 1] * 4; weight = bilinearWeightTable[i * 4 + 1]; red += distortedBuffer[pixelOffset + 0] * weight; green += distortedBuffer[pixelOffset + 1] * weight; blue += distortedBuffer[pixelOffset + 2] * weight; pixelOffset = bilinearDistortedToRectifideOffsetTable[i * 4 + 2] * 4; weight = bilinearWeightTable[i * 4 + 2]; red += distortedBuffer[pixelOffset + 0] * weight; green += distortedBuffer[pixelOffset + 1] * weight; blue += distortedBuffer[pixelOffset + 2] * weight; pixelOffset = bilinearDistortedToRectifideOffsetTable[i * 4 + 3] * 4; weight = bilinearWeightTable[i * 4 + 3]; red += distortedBuffer[pixelOffset + 0] * weight; green += distortedBuffer[pixelOffset + 1] * weight; blue += distortedBuffer[pixelOffset + 2] * weight; rectifideBuffer[rectifedBufferIndex + 0] = (byte)(red / blendFractionDenominator); rectifideBuffer[rectifedBufferIndex + 1] = (byte)(green / blendFractionDenominator); rectifideBuffer[rectifedBufferIndex + 2] = (byte)(blue / blendFractionDenominator); rectifideBuffer[rectifedBufferIndex + 3] = 255; } } else { for (int i = 0; i < bilinearDistortedToRectifideOffsetTable.Length / 4; i++) { int rectifedBufferIndex = i * 4; int pixelOffset = bilinearDistortedToRectifideOffsetTable[i * 4] * 4; int red = distortedBuffer[pixelOffset + 0]; ; int green = distortedBuffer[pixelOffset + 1]; int blue = distortedBuffer[pixelOffset + 2]; rectifideBuffer[rectifedBufferIndex + 0] = (byte)red; rectifideBuffer[rectifedBufferIndex + 1] = (byte)green; rectifideBuffer[rectifedBufferIndex + 2] = (byte)blue; rectifideBuffer[rectifedBufferIndex + 3] = 255; } } rectifideImage.MarkImageChanged(); }
public void CopyDepthBufferToImage(ImageBuffer destImage, RectangleInt viewport) { if (destImage.BitDepth != 32) { throw new Exception("We can only render to 32 bit dest at the moment."); } Byte[] destBuffer = destImage.GetBuffer(); viewport.Bottom = Math.Max(0, Math.Min(destImage.Height, viewport.Bottom)); viewport.Top = Math.Max(0, Math.Min(destImage.Height, viewport.Top)); double minZ = 5000; double maxZ = 0; for (int y = viewport.Bottom; y < viewport.Height; y++) { for (int x = viewport.Left; x < viewport.Right; x++) { double depthAtXY = depthBuffer[x][y]; if (depthAtXY < 5000) { minZ = Math.Min(minZ, depthAtXY); maxZ = Math.Max(maxZ, depthAtXY); } } } double divisor = maxZ - minZ; #if MULTI_THREAD System.Threading.Tasks.Parallel.For(viewport.Bottom, viewport.Height, y => // #else for (int y = viewport.Bottom; y < viewport.Height; y++) #endif { for (int x = viewport.Left; x < viewport.Right; x++) { int bufferOffset = destImage.GetBufferOffsetY(y); // we don't need to set this if we are anti-aliased int totalOffset = bufferOffset + x * 4; double depthXY = depthBuffer[x][y]; double rangedDepth = (depthXY - minZ) / divisor; double clampedDepth = Math.Max(0, Math.Min(255, rangedDepth * 255)); byte depthColor = (byte)(clampedDepth); destBuffer[totalOffset++] = depthColor; destBuffer[totalOffset++] = depthColor; destBuffer[totalOffset++] = depthColor; destBuffer[totalOffset] = 255; } } #if MULTI_THREAD ); #endif destImage.MarkImageChanged(); }