/// <summary> /// WIC <see cref="SharpDX.WIC.BitmapSource"/> から <see cref="SharpDX.Direct3D11.Texture2D"/> を作成する /// </summary> /// <param name="app"></param> /// <param name="bitmapSource">The WIC bitmap source</param> /// <param name="name">任意の名前</param> /// <returns>A Texture2D</returns> protected static MCTexture CreateTexture2DFromBitmap(Application app, SharpDX.WIC.BitmapSource bitmapSource, string name) { // WICイメージピクセルを受け取るためにDataStreamを割り当てます。 int stride = bitmapSource.Size.Width * 4; MCTexture tx = new MCTexture(app, name); using (var buffer = new SharpDX.DataStream(bitmapSource.Size.Height * stride, true, true)) { // WICの内容をバッファにコピーする bitmapSource.CopyPixels(stride, buffer); Texture123DDesc d = new Texture123DDesc(); d.D2 = new Texture2DDescription() { Width = bitmapSource.Size.Width, Height = bitmapSource.Size.Height, ArraySize = 1, BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource, Usage = SharpDX.Direct3D11.ResourceUsage.Immutable, CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None, Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm, MipLevels = 1, OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), }; if (tx.CreateTexture2D(0, d, new DataRectangle(buffer.DataPointer, stride)) == 1) { return(null); } } return(tx); }
private static Direct2D.Bitmap LoadFromFile(string filename, Direct2D.RenderTarget Direct2DTarget) { var factory = new WIC.ImagingFactory(); // Decode image var decoder = new WIC.BitmapDecoder(factory, filename, WIC.DecodeOptions.CacheOnLoad); var frameDecode = decoder.GetFrame(0); var source = new WIC.BitmapSource(frameDecode.NativePointer); var fc = new WIC.FormatConverter(factory); fc.Initialize( source, SharpDX.WIC.PixelFormat.Format32bppPBGRA, SharpDX.WIC.BitmapDitherType.None, null, 0.0f, SharpDX.WIC.BitmapPaletteType.Custom ); double dpX = 96.0f; double dpY = 96.0f; fc.GetResolution(out dpX, out dpY); Direct2D.BitmapProperties props = new Direct2D.BitmapProperties( new SharpDX.Direct2D1.PixelFormat(SharpDX.DXGI.Format.B8G8R8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied)); WIC.Bitmap bmp = new WIC.Bitmap(factory, fc, WIC.BitmapCreateCacheOption.CacheOnLoad); // Формируем изображения var Direct2DBitmap = SharpDX.Direct2D1.Bitmap.FromWicBitmap(Direct2DTarget, fc, props); // Cleanup factory.Dispose(); decoder.Dispose(); source.Dispose(); fc.Dispose(); return(Direct2DBitmap); }
/// <summary> /// Creates a <see cref="SharpDX.Direct3D11.Texture2D"/> from a WIC <see cref="SharpDX.WIC.BitmapSource"/> /// </summary> /// <param name="device">The Direct3D11 device</param> /// <param name="bitmapSource">The WIC bitmap source</param> /// <returns>A Texture2D</returns> public static Texture2D CreateTexture2DFromBitmap(Device device, BitmapSource bitmapSource) { // Allocate DataStream to receive the WIC image pixels int stride = bitmapSource.Size.Width * 4; using (var buffer = new DataStream(bitmapSource.Size.Height * stride, true, true)) { // Copy the content of the WIC to the buffer Rectangle rect = new Rectangle(); var methods = bitmapSource.GetType().GetMethods(); bitmapSource.GetType().GetMethods().First(item => item.Name == "CopyPixels").Invoke(bitmapSource, new object[] { stride, buffer }); // bitmapSource.CopyPixels(stride, buffer); return new Texture2D(device, new Texture2DDescription() { Width = bitmapSource.Size.Width, Height = bitmapSource.Size.Height, ArraySize = 1, BindFlags = BindFlags.ShaderResource, Usage = ResourceUsage.Immutable, CpuAccessFlags =CpuAccessFlags.None, Format = Format.R8G8B8A8_UNorm, MipLevels = 1, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SampleDescription(1, 0), }, new DataRectangle(buffer.DataPointer, stride)); } }
public WICBitmapSourceImage (WIC.BitmapSource bmp, double scale, Direct2DFactories factories = null) { if (bmp == null) throw new ArgumentNullException ("bmp"); this.bmp = bmp; this.scale = scale; this.factories = factories ?? Direct2DFactories.Shared; }
public WICBitmapSourceImage(WIC.BitmapSource bmp, Direct2DFactories factories = null) { if (bmp == null) { throw new ArgumentNullException("bmp"); } this.bmp = bmp; this.factories = factories ?? Direct2DFactories.Shared; }
/// <summary> /// Function to clip a bitmap. /// </summary> /// <param name="bitmap">Bitmap to clip.</param> /// <param name="buffer">Buffer containing clipped data.</param> private void ClipBitmap(WIC.BitmapSource bitmap, GorgonImageBuffer buffer) { using (var clipper = new WIC.BitmapClipper(Factory)) { clipper.Initialize(bitmap, new DX.Rectangle(0, 0, buffer.Width < bitmap.Size.Width ? buffer.Width : bitmap.Size.Width, buffer.Height < bitmap.Size.Height ? buffer.Height : bitmap.Size.Height)); clipper.CopyPixels(buffer.PitchInformation.RowPitch, buffer.Data.BasePointer, buffer.PitchInformation.SlicePitch); } }
/// <summary> /// Gets the bitmap. /// </summary> /// <param name="engineDevice">The engine device.</param> internal override D2D.Bitmap GetBitmap(EngineDevice engineDevice) { if (base.IsDisposed) { throw new ObjectDisposedException(this.GetType().Name); } D2D.Bitmap result = m_loadedBitmaps[engineDevice.DeviceIndex]; if (result == null) { using (Stream inputStream = m_resourceLink.OpenInputStream()) using (WicBitmapSourceInternal bitmapSourceWrapper = GraphicsHelper.LoadBitmapSource_D2D(inputStream)) { WIC.BitmapSource bitmapSource = bitmapSourceWrapper.Converter; // Store common properties about the bitmap if (!m_firstLoadDone) { m_firstLoadDone = true; m_pixelWidth = bitmapSource.Size.Width; m_pixelHeight = bitmapSource.Size.Height; if (m_totalFrameCount > 1) { m_framePixelWidth = m_pixelWidth / m_framesX; m_framePixelHeight = m_pixelHeight / m_framesY; } else { m_framePixelWidth = m_pixelWidth; m_framePixelHeight = m_pixelHeight; } bitmapSource.GetResolution(out m_dpiX, out m_dpyY); } // Load the bitmap into Direct2D result = D2D.Bitmap.FromWicBitmap( engineDevice.FakeRenderTarget2D, bitmapSource, new D2D.BitmapProperties(new D2D.PixelFormat( SharpDX.DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Premultiplied))); // Register loaded bitmap m_loadedBitmaps[engineDevice.DeviceIndex] = result; } } return(result); }
public IImage LoadImage(Stream stream) { var factories = Direct2DFactories.Shared; var d = new WIC.BitmapDecoder(factories.WICFactory, stream, WIC.DecodeOptions.CacheOnDemand); WIC.BitmapSource b = d.GetFrame(0); var renderFormat = WIC.PixelFormat.Format32bppPBGRA; if (b.PixelFormat != renderFormat) { //System.Diagnostics.Debug.WriteLine ("BMP FORMAT: " + b.PixelFormat); var c = new WIC.FormatConverter(factories.WICFactory); c.Initialize(b, renderFormat); //System.Diagnostics.Debug.WriteLine ("CO FORMAT: " + c.PixelFormat); b = c; } // Convert the BitmapSource to a Bitmap so we can allow the decoder to go out of memory return(new WICBitmapSourceImage(new WIC.Bitmap(factories.WICFactory, b, WIC.BitmapCreateCacheOption.CacheOnLoad), 1.0, factories)); }
/// <summary> /// Function to clip or scale the bitmap up or down to the size of the buffer. /// </summary> /// <param name="bitmap">Bitmap to scale.</param> /// <param name="filter">Filtering to apply to the scaled bitmap.</param> /// <param name="buffer">Buffer to receive the scaled bitmap.</param> /// <param name="clip">TRUE to clip, FALSE to scale.</param> /// <returns>TRUE if clipping/scaling was performed, FALSE if not.</returns> private bool ResizeBitmap(WIC.BitmapSource bitmap, WIC.BitmapInterpolationMode filter, GorgonImageBuffer buffer, bool clip) { if (!clip) { using (var scaler = new WIC.BitmapScaler(Factory)) { scaler.Initialize(bitmap, buffer.Width, buffer.Height, filter); scaler.CopyPixels(buffer.PitchInformation.RowPitch, buffer.Data.BasePointer, buffer.PitchInformation.SlicePitch); } return(true); } if ((buffer.Width >= bitmap.Size.Width) && (buffer.Height >= bitmap.Size.Height)) { return(false); } ClipBitmap(bitmap, buffer); return(true); }
public static d2.Bitmap LoadBitmap(this d2.RenderTarget renderTarget, Stream stream) { var bitmapDecoder = new wic.BitmapDecoder(DXGraphicsService.FactoryImaging, stream, wic.DecodeOptions.CacheOnDemand); wic.BitmapFrameDecode bitmapFrameDecode = bitmapDecoder.GetFrame(0); var bitmapSource = new wic.BitmapSource(bitmapFrameDecode.NativePointer); var formatConverter = new wic.FormatConverter(DXGraphicsService.FactoryImaging); formatConverter.Initialize(bitmapSource, wic.PixelFormat.Format32bppPBGRA); d2.Bitmap bitmap = d2.Bitmap.FromWicBitmap(renderTarget, formatConverter); formatConverter.Dispose(); /* todo: check to see if I need to register to dispose of this later... Can't comment this out because server side rendering will crash */ //bitmapSource.Dispose(); bitmapFrameDecode.Dispose(); bitmapDecoder.Dispose(); return(bitmap); }
public static Texture2D CreateTex2DFromBitmap(SharpDX.WIC.BitmapSource bsource, SharpDX.Direct3D11.Device device) { Texture2DDescription desc; desc.Width = bsource.Size.Width; desc.Height = bsource.Size.Height; desc.ArraySize = 1; desc.BindFlags = BindFlags.ShaderResource; desc.Usage = ResourceUsage.Default; desc.CpuAccessFlags = CpuAccessFlags.None; desc.Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm; desc.MipLevels = 1; desc.OptionFlags = ResourceOptionFlags.None; desc.SampleDescription.Count = 1; desc.SampleDescription.Quality = 0; using (DataStream s = new DataStream(bsource.Size.Height * bsource.Size.Width * 4, true, true)) { bsource.CopyPixels(bsource.Size.Width * 4, s); DataRectangle rect = new DataRectangle(s.DataPointer, bsource.Size.Width * 4); return(new Texture2D(device, desc, rect)); } }
public static D3D11.Texture2D CreateTexture2DFromBitmap(D3D11.Device device, WIC.BitmapSource bitmapSource) { // Allocate DataStream to receive the WIC image pixels int stride = bitmapSource.Size.Width * 4; using (var buffer = new SharpDX.DataStream(bitmapSource.Size.Height * stride, true, true)) { // Copy the content of the WIC to the buffer bitmapSource.CopyPixels(stride, buffer); return(new D3D11.Texture2D(device, new D3D11.Texture2DDescription() { Width = bitmapSource.Size.Width, Height = bitmapSource.Size.Height, ArraySize = 1, BindFlags = D3D11.BindFlags.ShaderResource, Usage = D3D11.ResourceUsage.Immutable, CpuAccessFlags = D3D11.CpuAccessFlags.None, Format = DXGI.Format.R8G8B8A8_UNorm, MipLevels = 1, OptionFlags = D3D11.ResourceOptionFlags.None, SampleDescription = new DXGI.SampleDescription(1, 0), }, new SharpDX.DataRectangle(buffer.DataPointer, stride))); } }
public BblBitmapSource(SharpDX.WIC.BitmapSource source) { WICBitmapSource = source; }
private async Task SetImageAsync(StorageFile file) { if (file == null) { return; } this.currentFile = file; //// カラマネする場合 // モニタプロファイルのStreamを作成 // ※物理モニタがない環境だと例外を吐く var profileStream = await DisplayInformation.GetForCurrentView().GetColorProfileAsync(); // Stream → Bytes var profileBytes = new byte[profileStream.Size]; var reader = new DataReader(profileStream); await reader.LoadAsync((uint)profileStream.Size); reader.ReadBytes(profileBytes); // モニタプロファイルのColorContextを作成 var factory = new ImagingFactory(); // 割とあちこちで使う var displayProfile = new ColorContext(factory); displayProfile.InitializeFromMemory(DataStream.Create(profileBytes, true, false)); using (var stream = await currentFile.OpenAsync(FileAccessMode.Read)) { // デコーダーでファイルからフレームを取得 var decoder = new BitmapDecoder(factory, stream.AsStream(), DecodeOptions.CacheOnDemand); if (decoder.FrameCount < 1) { return; } var frame = decoder.GetFrame(0); // 埋め込みプロファイル取得 var srcColorContexts = frame.TryGetColorContexts(factory); var untaggedOrUnsupported = srcColorContexts == null || srcColorContexts.Length < 1; // プロファイルが読み込めなかった場合はsRGBとみなす var sourceProfile = !untaggedOrUnsupported ? srcColorContexts[0] : sRGBContext; SharpDX.WIC.BitmapSource transformSource = frame; if (untaggedOrUnsupported) { // プロファイルが読み込めなかった場合はsRGBを適用したいので、FormatConverterで32bppPBGRAへ変換 // 変換しなかった場合、色変換時にCMYK画像をsRGBとして扱ってしまうことでエラーが発生する var converter = new FormatConverter(factory); converter.Initialize(frame, PixelFormat.Format32bppPBGRA); transformSource = converter; } // ColorTransformを通すことで色変換ができる var transform = new ColorTransform(factory); transform.Initialize(transformSource, sourceProfile, displayProfile, PixelFormat.Format32bppPBGRA); var stride = transform.Size.Width * 4; // 横1行のバイト数 var size = stride * transform.Size.Height; var bytes = new byte[size]; transform.CopyPixels(bytes, stride); // Byte配列にピクセルデータをコピー // ピクセルデータをWriteableBitmapに書き込み var bitmap = new WriteableBitmap(transform.Size.Width, transform.Size.Height); using (var s = bitmap.PixelBuffer.AsStream()) { await s.WriteAsync(bytes, 0, size); } this.Image1.Source = bitmap; } ////// カラマネしない場合 //var bitmapImage = new BitmapImage(); //var fileStream = await file.OpenStreamForReadAsync(); //await bitmapImage.SetSourceAsync(fileStream.AsRandomAccessStream()); //this.Image1.Source = bitmapImage; }
/// <summary> /// Function to perform conversion/transformation of a bitmap. /// </summary> /// <param name="sourceData">WIC bitmap to transform.</param> /// <param name="destData">Destination data buffer.</param> /// <param name="rowPitch">Number of bytes per row in the image.</param> /// <param name="slicePitch">Number of bytes in total for the image.</param> /// <param name="destFormat">Destination format for transformation.</param> /// <param name="isSourcesRGB">TRUE if the source format is sRGB.</param> /// <param name="isDestsRGB">TRUE if the destination format is sRGB.</param> /// <param name="dither">Dithering to apply to images that get converted to a lower bit depth.</param> /// <param name="destRect">Rectangle containing the area to scale or clip</param> /// <param name="clip">TRUE to perform clipping instead of scaling.</param> /// <param name="scaleFilter">Filter to apply to scaled data.</param> public void TransformImageData(WIC.BitmapSource sourceData, IntPtr destData, int rowPitch, int slicePitch, Guid destFormat, bool isSourcesRGB, bool isDestsRGB, ImageDithering dither, Rectangle destRect, bool clip, ImageFilter scaleFilter) { WIC.BitmapSource source = sourceData; WIC.FormatConverter converter = null; WIC.BitmapClipper clipper = null; WIC.BitmapScaler scaler = null; WIC.ColorContext sourceContext = null; WIC.ColorContext destContext = null; WIC.ColorTransform sRGBTransform = null; try { if (destFormat != Guid.Empty) { if (sourceData.PixelFormat != destFormat) { converter = new WIC.FormatConverter(Factory); if (!converter.CanConvert(sourceData.PixelFormat, destFormat)) { throw new GorgonException(GorgonResult.FormatNotSupported, string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, destFormat)); } converter.Initialize(source, destFormat, (WIC.BitmapDitherType)dither, null, 0, WIC.BitmapPaletteType.Custom); source = converter; } if ((isDestsRGB) || (isSourcesRGB)) { sRGBTransform = new WIC.ColorTransform(Factory); sourceContext = new WIC.ColorContext(Factory); destContext = new WIC.ColorContext(Factory); sourceContext.InitializeFromExifColorSpace(isSourcesRGB ? 1 : 2); destContext.InitializeFromExifColorSpace(isDestsRGB ? 1 : 2); sRGBTransform.Initialize(source, sourceContext, destContext, destFormat); source = sRGBTransform; } } if (destRect.IsEmpty) { source.CopyPixels(rowPitch, destData, slicePitch); return; } Guid pixelFormat = source.PixelFormat; if (!clip) { scaler = new WIC.BitmapScaler(Factory); scaler.Initialize(source, destRect.Width, destRect.Height, (WIC.BitmapInterpolationMode)scaleFilter); source = scaler; } else { destRect.Width = destRect.Width.Min(source.Size.Width); destRect.Height = destRect.Height.Min(source.Size.Height); if ((destRect.Width < source.Size.Width) || (destRect.Height < source.Size.Height)) { clipper = new WIC.BitmapClipper(Factory); clipper.Initialize(source, new DX.Rectangle(destRect.X, destRect.Y, destRect.Width, destRect.Height)); source = clipper; destRect.X = 0; destRect.Y = 0; } } // We have a change of format (probably due to the filter when scaling)... so we need to convert. if (source.PixelFormat != pixelFormat) { converter = new WIC.FormatConverter(Factory); if (!converter.CanConvert(source.PixelFormat, pixelFormat)) { throw new GorgonException(GorgonResult.FormatNotSupported, string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, pixelFormat)); } converter.Initialize(source, pixelFormat, WIC.BitmapDitherType.None, null, 0, WIC.BitmapPaletteType.Custom); source = converter; } source.CopyPixels(rowPitch, destData, slicePitch); } finally { if (converter != null) { converter.Dispose(); } if (sourceContext != null) { sourceContext.Dispose(); } if (destContext != null) { destContext.Dispose(); } if (sRGBTransform != null) { sRGBTransform.Dispose(); } if (scaler != null) { scaler.Dispose(); } if (clipper != null) { clipper.Dispose(); } } }
/// <summary> /// Function to convert the format of a bitmap into the format of the buffer. /// </summary> /// <param name="sourceFormat">Format to convert from.</param> /// <param name="destFormat">Format to convert into.</param> /// <param name="dithering">Dithering to apply.</param> /// <param name="filter">Filtering to apply to scaled bitmaps.</param> /// <param name="bitmap">Bitmap to convert.</param> /// <param name="bitmapPalette">Palette for the bitmap.</param> /// <param name="alphaValue">Value of pixel to consider transparent.</param> /// <param name="buffer">Buffer holding the converted data.</param> /// <param name="scale">TRUE to scale when converting, FALSE to keep at original size.</param> /// <param name="clip">TRUE to perform clipping, FALSE to keep at original size.</param> private void ConvertFormat(Guid sourceFormat, Guid destFormat, WIC.BitmapDitherType dithering, WIC.BitmapInterpolationMode filter, WIC.BitmapSource bitmap, WIC.Palette bitmapPalette, int alphaValue, GorgonImageBuffer buffer, bool scale, bool clip) { WIC.BitmapSource source = bitmap; double alphaPercent = alphaValue / 255.0; var paletteType = WIC.BitmapPaletteType.Custom; // If we have a palette, then confirm that the dithering method is valid. if (bitmapPalette != null) { // Do not apply dithering if we're using // a custom palette and request ordered dithering. switch (dithering) { case WIC.BitmapDitherType.Ordered4x4: case WIC.BitmapDitherType.Ordered8x8: case WIC.BitmapDitherType.Ordered16x16: if (bitmapPalette.TypeInfo == WIC.BitmapPaletteType.Custom) { dithering = WIC.BitmapDitherType.None; } break; } paletteType = bitmapPalette.TypeInfo; } try { // Create a scaler if need one. if ((scale) && (!clip)) { var scaler = new WIC.BitmapScaler(Factory); scaler.Initialize(bitmap, buffer.Width, buffer.Height, filter); source = scaler; } // Create a clipper if we want to clip and the image needs resizing. if ((clip) && (scale) && ((buffer.Width < bitmap.Size.Width) || (buffer.Height < bitmap.Size.Height))) { var clipper = new WIC.BitmapClipper(Factory); clipper.Initialize(bitmap, new DX.Rectangle(0, 0, buffer.Width < bitmap.Size.Width ? buffer.Width : bitmap.Size.Width, buffer.Height < bitmap.Size.Height ? buffer.Height : bitmap.Size.Height)); source = clipper; } using (var converter = new WIC.FormatConverter(Factory)) { if (!converter.CanConvert(sourceFormat, destFormat)) { throw new GorgonException(GorgonResult.FormatNotSupported, string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, buffer.Format)); } converter.Initialize(source, destFormat, dithering, bitmapPalette, alphaPercent, paletteType); if (!scale) { int rowPitch = (GetBitsPerPixel(destFormat) * bitmap.Size.Width + 7) / 8; int slicePitch = rowPitch * bitmap.Size.Height; if ((rowPitch != buffer.PitchInformation.RowPitch) || (slicePitch != buffer.PitchInformation.SlicePitch)) { throw new GorgonException(GorgonResult.CannotWrite, Resources.GORGFX_IMAGE_PITCH_TOO_SMALL); } } converter.CopyPixels(buffer.PitchInformation.RowPitch, buffer.Data.BasePointer, buffer.PitchInformation.SlicePitch); } } finally { if (source != bitmap) { source.Dispose(); } } }