// NOTE: Bitmap objects does not support parallel read-outs blame Microsoft /// <summary> /// Initializes a new instance of the <see cref="cImage"/> class from a <see cref="BitmapSource"/> instance. /// </summary> /// <param name="bitmapSource">The bitmap.</param> public static cImage FromBitmapSource(BitmapSource bitmapSource) { if (bitmapSource == null) { return(null); } var result = new cImage(bitmapSource.PixelWidth, bitmapSource.PixelHeight); var finalSource = bitmapSource; if (bitmapSource.Format != PixelFormats.Bgra32) { var formatedBitmapSource = new FormatConvertedBitmap(); formatedBitmapSource.BeginInit(); formatedBitmapSource.Source = bitmapSource; formatedBitmapSource.DestinationFormat = PixelFormats.Bgra32; formatedBitmapSource.EndInit(); finalSource = formatedBitmapSource; } var writeableBitmap = new WriteableBitmap(finalSource); using (var data = writeableBitmap.LockData()) _CopyPixels(0, 0, result._width, result._height, data.Bitmap.BackBuffer, data.Bitmap.BackBufferStride, data.Bitmap.PixelWidth, data.Bitmap.PixelHeight, result._imageData, result._width, result._width, result._height); return(result); }
public cImage ApplyXbrz(int scale) { var result = new cImage(this.Width * scale, this.Height * scale); switch (scale) { case 2: libXBRz.ScaleImage(libXBRz.ScaleSize.TIMES2, this.GetImageData(), result.GetImageData(), Width, Height, 0, 0, Width, Height); break; case 3: libXBRz.ScaleImage(libXBRz.ScaleSize.TIMES3, this.GetImageData(), result.GetImageData(), Width, Height, 0, 0, Width, Height); break; case 4: libXBRz.ScaleImage(libXBRz.ScaleSize.TIMES4, this.GetImageData(), result.GetImageData(), Width, Height, 0, 0, Width, Height); break; case 5: libXBRz.ScaleImage(libXBRz.ScaleSize.TIMES5, this.GetImageData(), result.GetImageData(), Width, Height, 0, 0, Width, Height); break; default: break; } return(result); }
// NOTE: Bitmap objects does not support parallel read-outs blame Microsoft /// <summary> /// Initializes a new instance of the <see cref="cImage"/> class from a <see cref="Bitmap"/> instance. /// </summary> /// <param name="bitmap">The bitmap.</param> public static cImage FromBitmap(Bitmap bitmap) { if (bitmap == null) return (null); var result = new cImage(bitmap.Width, bitmap.Height); var height = result._height; var width = result._width; var bitmapData = bitmap.LockBits( new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb ); var intFillX = bitmapData.Stride - bitmapData.Width * 4; unsafe { var ptrOffset = (byte*)bitmapData.Scan0.ToPointer(); for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { result[x, y] = new sPixel(*(ptrOffset + 2), *(ptrOffset + 1), *(ptrOffset + 0), *(ptrOffset + 3)); ptrOffset += 4; } ptrOffset += intFillX; } } bitmap.UnlockBits(bitmapData); return (result); }
// NOTE: Bitmap objects does not support parallel read-outs blame Microsoft /// <summary> /// Initializes a new instance of the <see cref="cImage"/> class from a <see cref="Bitmap"/> instance. /// </summary> /// <param name="bitmap">The bitmap.</param> public static cImage FromBitmap(Bitmap bitmap) { if (bitmap == null) { return(null); } var result = new cImage(bitmap.Width, bitmap.Height); var height = result._height; var width = result._width; var bitmapData = bitmap.LockBits( new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb ); var intFillX = bitmapData.Stride - bitmapData.Width * 4; unsafe { var ptrOffset = (byte *)bitmapData.Scan0.ToPointer(); for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { result[x, y] = new sPixel(*(ptrOffset + 2), *(ptrOffset + 1), *(ptrOffset + 0), *(ptrOffset + 3)); ptrOffset += 4; } ptrOffset += intFillX; } } bitmap.UnlockBits(bitmapData); return(result); }
/// <summary> /// Initializes a new instance of the <see cref="cImage"/> class from a given one. /// </summary> /// <param name="sourceImage">The source image.</param> public cImage(cImage sourceImage) : this(sourceImage == null ? 0 : sourceImage._width, sourceImage == null ? 0 : sourceImage._height) { if (sourceImage == null) { return; } for (long index = 0; index < sourceImage._imageData.LongLength; index++) { this._imageData[index] = sourceImage._imageData[index]; } }
/// <summary> /// Applies the XBR pixel scaler. /// </summary> /// <param name="type">The type of scaler to use.</param> /// <param name="filterRegion">The filter region, if any.</param> /// <returns> /// The rescaled image. /// </returns> public cImage ApplyScaler(XbrzScalerType type, Rectangle? filterRegion = null) { var info = GetPixelScalerInfo(type); var scaleX = info.Item1; var scaleY = info.Item2; var scaler = info.Item3; if (filterRegion == null) filterRegion = new Rectangle(0, 0, this.Width, this.Height); var result = new cImage(this.Width * scaleX, this.Height * scaleY); // TODO: generic pixel loop scaler(this.GetImageData(), result.GetImageData(), this.Width, this.Height, filterRegion.Value.Left, filterRegion.Value.Top, filterRegion.Value.Right, filterRegion.Value.Bottom); return (result); }
// NOTE: Bitmap objects does not support parallel read-outs blame Microsoft /// <summary> /// Initializes a new instance of the <see cref="cImage"/> class from a <see cref="Bitmap"/> instance. /// </summary> /// <param name="bitmap">The bitmap.</param> public static cImage FromBitmap(Bitmap bitmap) { if (bitmap == null) { return(null); } var result = new cImage(bitmap.Width, bitmap.Height); using (var data = bitmap.LockForRead()) { var bitmapData = data.BitmapData; _CopyPixels(0, 0, result._width, result._height, bitmapData.Scan0, bitmapData.Stride, bitmapData.Width, bitmapData.Height, result._imageData, result._width, result._width, result._height); } return(result); }
/// <summary> /// Applies the XBR pixel scaler. /// </summary> /// <param name="type">The type of scaler to use.</param> /// <param name="filterRegion">The filter region, if any.</param> /// <returns> /// The rescaled image. /// </returns> public cImage ApplyScaler(XbrzScalerType type, Rectangle?filterRegion = null) { var info = GetPixelScalerInfo(type); var scaleX = info.Item1; var scaleY = info.Item2; var scaler = info.Item3; if (filterRegion == null) { filterRegion = new Rectangle(0, 0, this.Width, this.Height); } var result = new cImage(this.Width * scaleX, this.Height * scaleY); // TODO: generic pixel loop scaler(this.GetImageData(), result.GetImageData(), this.Width, this.Height, filterRegion.Value.Left, filterRegion.Value.Top, filterRegion.Value.Right, filterRegion.Value.Bottom); return(result); }
private void button1_Click(object sender, EventArgs e) { var Item = (TextureElement)TextureList.SelectedItem; var InBitmap = (Bitmap)TextureView.Image; Bitmap OutBitmap; if (false) { var OutImage = new cImage(InBitmap.Width * 2, InBitmap.Height * 2); libXBR.Xbr2X(cImage.FromBitmap(InBitmap), 0, 0, OutImage, 0, 0, true); OutBitmap = OutImage.ToBitmap(); } else { OutBitmap = (new Engine(new ColorAlphaLerp(), new ColorAlphaThreshold(32, 32, 32, 32))).Process(InBitmap); } Item.TextureOpengl.SetData(OutBitmap.GetChannelsDataInterleaved(BitmapChannelList.RGBA).CastToStructArray<OutputPixel>(), OutBitmap.Width, OutBitmap.Height); UpdateTexture(); TextureList.Focus(); }
/// <summary> /// Initializes a new instance of the <see cref="cImage"/> class by filtering a given one. /// </summary> /// <param name="sourceImage">The source image.</param> /// <param name="filterFunction">The filter.</param> public cImage(cImage sourceImage, Func <sPixel, sPixel> filterFunction) : this(sourceImage?._width ?? 0, sourceImage?._height ?? 0) { if (sourceImage == null) { return; } var width = sourceImage._width; Parallel.ForEach(Partitioner.Create(0, this._height), () => 0, (range, _, threadStorage) => { for (var y = range.Item2; y > range.Item1;) { --y; for (var x = width; x > 0;) { --x; this[x, y] = filterFunction(sourceImage[x, y]); } } return(threadStorage); }, _ => { }); }
/// <summary> /// Initializes a new greyscale instance of the <see cref="cImage"/> class by filtering a given one. /// </summary> /// <param name="sourceImage">The source image.</param> /// <param name="colorFilter">The greyscale filter.</param> public cImage(cImage sourceImage, Func <sPixel, byte> colorFilter) : this(sourceImage == null ? 0 : sourceImage._width, sourceImage == null ? 0 : sourceImage._height) { if (sourceImage == null) { return; } var width = sourceImage._width; Parallel.ForEach(Partitioner.Create(0, this._height), () => 0, (range, _, threadStorage) => { for (var y = range.Item2; y > range.Item1;) { --y; for (var x = width; x > 0;) { --x; this[x, y] = sPixel.FromGrey(colorFilter(sourceImage[x, y])); } } return(threadStorage); }, _ => { }); }
private cImage _RunLoop(Rectangle? filterRegion, byte scaleX, byte scaleY, Action<PixelWorker<sPixel>> scaler) { var startX = filterRegion == null ? 0 : Math.Max(0, filterRegion.Value.Left); var startY = filterRegion == null ? 0 : Math.Max(0, filterRegion.Value.Top); var endX = filterRegion == null ? this.Width : Math.Min(this.Width, filterRegion.Value.Right); var endY = filterRegion == null ? this.Height : Math.Min(this.Height, filterRegion.Value.Bottom); var width = endX - startX; var result = new cImage(width * scaleX, (endY - startY) * scaleY); Parallel.ForEach( Partitioner.Create(startY, endY), () => 0, (range, _, threadStorage) => { var threadSrcMinY = range.Item1; var threadSrcMaxY = range.Item2; var targetY = (threadSrcMinY - startY) * scaleY; for (var sourceY = threadSrcMinY; sourceY < threadSrcMaxY;++sourceY) { var worker=new PixelWorker<sPixel>( this.GetImageData(), startX, sourceY, this._width, this._height, this._horizontalOutOfBoundsHandler, this._verticalOutOfBoundsHandler, result.GetImageData(), 0, targetY, result._width ); var xRange=width; while(xRange>=64){ xRange-=64; scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); } for (; xRange>0;--xRange) { scaler(worker); worker.IncrementX(scaleX); } targetY += scaleY; } return (threadStorage); }, _ => { } ); return(result); }
public cImage Apply(cImage source) { return (this._planeExtractionFunction(source)); }
public cImage Apply(cImage source, int width, int height) { Contract.Requires(source != null); return (source.ApplyScaler(this._type, width, height)); }
public override cImage Apply(cImage source) { Contract.Requires(source != null); return (source.ApplyScaler(this._type)); }
/// <summary> /// Filters the image. /// </summary> /// <param name="source">The source.</param> /// <param name="method">The method.</param> /// <param name="targetWidth">Width of the target.</param> /// <param name="targetHeight">Height of the target.</param> /// <param name="horizontalBh">The horizontal bounds handling.</param> /// <param name="verticalBh">The vertical bounds handling.</param> /// <param name="useThresholds">if set to <c>true</c> [use thresholds].</param> /// <param name="useCenteredGrid">if set to <c>true</c> [use centered grid].</param> /// <param name="repetitionCount">The repetition count.</param> /// <param name="radius">The radius.</param> /// <returns></returns> internal static cImage FilterImage(cImage source, IImageManipulator method, ushort targetWidth, ushort targetHeight, OutOfBoundsMode horizontalBh, OutOfBoundsMode verticalBh, bool useThresholds, bool useCenteredGrid, byte repetitionCount, float radius) { Contract.Requires(source != null); sPixel.AllowThresholds = useThresholds; source.HorizontalOutOfBoundsMode = horizontalBh; source.VerticalOutOfBoundsMode = verticalBh; cImage result = null; var scaler = method as AScaler; var interpolator = method as Interpolator; var planeExtractor = method as PlaneExtractor; var resampler = method as Resampler; var radiusResampler = method as RadiusResampler; if (scaler != null) { result = source; for (var i = 0; i < repetitionCount; i++) result = scaler.Apply(result); } else if (interpolator != null) if (targetWidth <= 0 || targetHeight <= 0) MessageBox.Show(Resources.txNeedWidthAndHeightAboveZero, Resources.ttNeedWidthAndHeightAboveZero, MessageBoxButtons.OK, MessageBoxIcon.Stop); else result = interpolator.Apply(source, targetWidth, targetHeight); else if (planeExtractor != null) result = planeExtractor.Apply(source); else if (resampler != null) if (targetWidth <= 0 || targetHeight <= 0) MessageBox.Show(Resources.txNeedWidthAndHeightAboveZero, Resources.ttNeedWidthAndHeightAboveZero, MessageBoxButtons.OK, MessageBoxIcon.Stop); else result = resampler.Apply(source, targetWidth, targetHeight, useCenteredGrid); else if (radiusResampler != null) if (targetWidth <= 0 || targetHeight <= 0) MessageBox.Show(Resources.txNeedWidthAndHeightAboveZero, Resources.ttNeedWidthAndHeightAboveZero, MessageBoxButtons.OK, MessageBoxIcon.Stop); else result = radiusResampler.Apply(source, targetWidth, targetHeight, radius, useCenteredGrid); return (result); }
private cImage _RunLoop(Rectangle?filterRegion, byte scaleX, byte scaleY, Action <PixelWorker <sPixel> > scaler) { var startX = filterRegion == null ? 0 : Math.Max(0, filterRegion.Value.Left); var startY = filterRegion == null ? 0 : Math.Max(0, filterRegion.Value.Top); var endX = filterRegion == null ? this.Width : Math.Min(this.Width, filterRegion.Value.Right); var endY = filterRegion == null ? this.Height : Math.Min(this.Height, filterRegion.Value.Bottom); var width = endX - startX; var result = new cImage(width * scaleX, (endY - startY) * scaleY); Parallel.ForEach( Partitioner.Create(startY, endY), () => 0, (range, _, threadStorage) => { var threadSrcMinY = range.Item1; var threadSrcMaxY = range.Item2; var targetY = (threadSrcMinY - startY) * scaleY; for (var sourceY = threadSrcMinY; sourceY < threadSrcMaxY; ++sourceY) { var worker = new PixelWorker <sPixel>( i => this.GetImageData()[i], startX, sourceY, this._width, this._height, this._width, this._horizontalOutOfBoundsHandler, this._verticalOutOfBoundsHandler, (i, c) => result.GetImageData()[i] = c, 0, targetY, result._width ); var xRange = width; while (xRange >= 64) { xRange -= 64; scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); scaler(worker); worker.IncrementX(scaleX); } for (; xRange > 0; --xRange) { scaler(worker); worker.IncrementX(scaleX); } targetY += scaleY; } return(threadStorage); }, _ => { } ); return(result); }
/// <summary> /// Initializes a new instance of the <see cref="cImage"/> class from a given one. /// </summary> /// <param name="sourceImage">The source image.</param> public cImage(cImage sourceImage) : this(sourceImage == null ? 0 : sourceImage._width, sourceImage == null ? 0 : sourceImage._height) { if (sourceImage == null) return; for (long index = 0; index < sourceImage._imageData.LongLength; index++) this._imageData[index] = sourceImage._imageData[index]; }
/// <summary> /// Initializes a new greyscale instance of the <see cref="cImage"/> class by filtering a given one. /// </summary> /// <param name="sourceImage">The source image.</param> /// <param name="colorFilter">The greyscale filter.</param> public cImage(cImage sourceImage, Func<sPixel, byte> colorFilter) : this(sourceImage == null ? 0 : sourceImage._width, sourceImage == null ? 0 : sourceImage._height) { if (sourceImage == null) return; var width = sourceImage._width; Parallel.ForEach(Partitioner.Create(0, this._height), () => 0, (range, _, threadStorage) => { for (var y = range.Item2; y > range.Item1; ) { --y; for (var x = width; x > 0; ) { --x; this[x, y] = sPixel.FromGrey(colorFilter(sourceImage[x, y])); } } return (threadStorage); }, _ => { }); }
/// <summary> /// Initializes a new instance of the <see cref="cImage"/> class by filtering a given one. /// </summary> /// <param name="sourceImage">The source image.</param> /// <param name="filterFunction">The filter.</param> public cImage(cImage sourceImage, Func<sPixel, sPixel> filterFunction) : this(sourceImage == null ? 0 : sourceImage._width, sourceImage == null ? 0 : sourceImage._height) { if (sourceImage == null) return; var width = sourceImage._width; #if !NET35 Parallel.ForEach(Partitioner.Create(0, this._height), () => 0, (range, _, threadStorage) => { for (var y = range.Item2; y > range.Item1; ) { --y; for (var x = width; x > 0; ) { --x; this[x, y] = filterFunction(sourceImage[x, y]); } } return (threadStorage); }, _ => { }); #else for (var y = this._height; y > 0; ) { --y; for (var x = width; x > 0; ) { --x; this[x, y] = filterFunction(sourceImage[x, y]); } } #endif }
public cImage Apply(cImage source, int width, int height, float radius, bool useCenteredGrid) { Contract.Requires(source != null); return (source.ApplyScaler(this._type, width, height, radius, useCenteredGrid)); }
public abstract cImage Apply(cImage source);
public override cImage Apply(cImage source) { Contract.Requires(source != null); return (source.ApplyScaler(this._type, this._allowAlphaBlending)); }