private static Texture DecodeMultiframe(ImagingFactory imagingFactory, WicFlags flags, TextureDescription description, BitmapDecoder decoder) { var texture = new Texture(description); Guid dstFormat = ToWic(description.Format, false); for (int index = 0; index < description.ArraySize; ++index) { var image = texture.Images[index]; using (var frame = decoder.GetFrame(index)) { var pfGuid = frame.PixelFormat; var size = frame.Size; if (size.Width == description.Width && size.Height == description.Height) { // This frame does not need resized if (pfGuid == dstFormat) { frame.CopyPixels(image.Data, image.RowPitch); } else { using (var converter = new FormatConverter(imagingFactory)) { converter.Initialize(frame, dstFormat, GetWicDither(flags), null, 0, BitmapPaletteType.Custom); converter.CopyPixels(image.Data, image.RowPitch); } } } else { // This frame needs resizing using (var scaler = new BitmapScaler(imagingFactory)) { scaler.Initialize(frame, description.Width, description.Height, GetWicInterp(flags)); Guid pfScaler = scaler.PixelFormat; if (pfScaler == dstFormat) { scaler.CopyPixels(image.Data, image.RowPitch); } else { // The WIC bitmap scaler is free to return a different pixel format than the source image, so here we // convert it to our desired format using (var converter = new FormatConverter(imagingFactory)) { converter.Initialize(scaler, dstFormat, GetWicDither(flags), null, 0, BitmapPaletteType.Custom); converter.CopyPixels(image.Data, image.RowPitch); } } } } } } return texture; }
public WicBitmapImpl(Stream stream, int decodeSize, bool horizontal, Avalonia.Visuals.Media.Imaging.BitmapInterpolationMode interpolationMode) { _decoder = new BitmapDecoder(Direct2D1Platform.ImagingFactory, stream, DecodeOptions.CacheOnLoad); var frame = _decoder.GetFrame(0); // now scale that to the size that we want var realScale = horizontal ? ((double)frame.Size.Height / frame.Size.Width) : ((double)frame.Size.Width / frame.Size.Height); PixelSize desired; if (horizontal) { desired = new PixelSize(decodeSize, (int)(realScale * decodeSize)); } else { desired = new PixelSize((int)(realScale * decodeSize), decodeSize); } if (frame.Size.Width != desired.Width || frame.Size.Height != desired.Height) { using (var scaler = new BitmapScaler(Direct2D1Platform.ImagingFactory)) { scaler.Initialize(frame, desired.Width, desired.Height, ConvertInterpolationMode(interpolationMode)); WicImpl = new Bitmap(Direct2D1Platform.ImagingFactory, scaler, BitmapCreateCacheOption.CacheOnLoad); } } else { WicImpl = new Bitmap(Direct2D1Platform.ImagingFactory, frame, BitmapCreateCacheOption.CacheOnLoad); } Dpi = new Vector(96, 96); }
//------------------------------------------------------------------------------------- // Decodes an image array, resizing/format converting as needed //------------------------------------------------------------------------------------- private static Image DecodeMultiframe(WICFlags flags, ImageDescription metadata, BitmapDecoder decoder) { var image = Image.New(metadata); Guid sourceGuid; if (!ToWIC(metadata.Format, out sourceGuid)) { return(null); } for (int index = 0; index < metadata.ArraySize; ++index) { var pixelBuffer = image.PixelBuffer[index, 0]; using (var frame = decoder.GetFrame(index)) { var pfGuid = frame.PixelFormat; var size = frame.Size; if (pfGuid == sourceGuid) { if (size.Width == metadata.Width && size.Height == metadata.Height) { // This frame does not need resized or format converted, just copy... frame.CopyPixels(pixelBuffer.RowStride, pixelBuffer.DataPointer, pixelBuffer.BufferStride); } else { // This frame needs resizing, but not format converted using (var scaler = new BitmapScaler(Factory)) { scaler.Initialize(frame, metadata.Width, metadata.Height, GetWICInterp(flags)); scaler.CopyPixels(pixelBuffer.RowStride, pixelBuffer.DataPointer, pixelBuffer.BufferStride); } } } else { // This frame required format conversion using (var converter = new FormatConverter(Factory)) { converter.Initialize(frame, pfGuid, GetWICDither(flags), null, 0, BitmapPaletteType.Custom); if (size.Width == metadata.Width && size.Height == metadata.Height) { converter.CopyPixels(pixelBuffer.RowStride, pixelBuffer.DataPointer, pixelBuffer.BufferStride); } else { // This frame needs resizing, but not format converted using (var scaler = new BitmapScaler(Factory)) { scaler.Initialize(frame, metadata.Width, metadata.Height, GetWICInterp(flags)); scaler.CopyPixels(pixelBuffer.RowStride, pixelBuffer.DataPointer, pixelBuffer.BufferStride); } } } } } } return(image); }
public bool GetThumbnail(Stream stream, int width, int height, bool cachedOnly, out byte[] imageData, out ImageType imageType) { imageData = null; imageType = ImageType.Unknown; // No support for cache if (cachedOnly) { return(false); } try { if (stream.CanSeek) { stream.Seek(0, SeekOrigin.Begin); } // open the image file for reading using (var factory = new ImagingFactory2()) using (var inputStream = new WICStream(factory, stream)) using (var decoder = new BitmapDecoder(factory, inputStream, DecodeOptions.CacheOnLoad)) using (var scaler = new BitmapScaler(factory)) using (var output = new MemoryStream()) using (var encoder = new BitmapEncoder(factory, ContainerFormatGuids.Jpeg)) { // decode the loaded image to a format that can be consumed by D2D BitmapSource source = decoder.GetFrame(0); // Scale down larger images int sourceWidth = source.Size.Width; int sourceHeight = source.Size.Height; if (width > 0 && height > 0 && (sourceWidth > width || sourceHeight > height)) { if (sourceWidth <= height) { width = sourceWidth; } int newHeight = sourceHeight * height / sourceWidth; if (newHeight > height) { // Resize with height instead width = sourceWidth * height / sourceHeight; newHeight = height; } scaler.Initialize(source, width, newHeight, BitmapInterpolationMode.Fant); source = scaler; } encoder.Initialize(output); using (var bitmapFrameEncode = new BitmapFrameEncode(encoder)) { // Create image encoder var wicPixelFormat = PixelFormat.FormatDontCare; bitmapFrameEncode.Initialize(); bitmapFrameEncode.SetSize(source.Size.Width, source.Size.Height); bitmapFrameEncode.SetPixelFormat(ref wicPixelFormat); bitmapFrameEncode.WriteSource(source); bitmapFrameEncode.Commit(); encoder.Commit(); } imageData = output.ToArray(); imageType = ImageType.Jpeg; return(true); } } catch (Exception e) { // ServiceRegistration.Get<ILogger>().Warn("WICThumbnailProvider: Error loading bitmapSource from file data stream", e); return(false); } }
public bool GetThumbnail(Stream stream, int width, int height, bool cachedOnly, out byte[] imageData, out ImageType imageType) { imageData = null; imageType = ImageType.Unknown; // No support for cache if (cachedOnly) { return(false); } Bitmap cachedBitmap = null; // used only for rotation try { if (stream.CanSeek) { stream.Seek(0, SeekOrigin.Begin); } // open the image file for reading using (var factory = new ImagingFactory2()) using (var inputStream = new WICStream(factory, stream)) using (var decoder = new BitmapDecoder(factory, inputStream, DecodeOptions.CacheOnLoad)) using (var rotator = new BitmapFlipRotator(factory)) using (var scaler = new BitmapScaler(factory)) using (var output = new MemoryStream()) { // decode the loaded image to a format that can be consumed by D2D BitmapSource source = decoder.GetFrame(0); // Prefer PNG output for source PNG and for source formats with Alpha channel var usePngOutput = decoder.DecoderInfo.FriendlyName.StartsWith("PNG") || PixelFormat.GetBitsPerPixel(source.PixelFormat) == 32; BitmapTransformOptions bitmapTransformationOptions = BitmapTransformOptions.Rotate0; BitmapFrameDecode frame = source as BitmapFrameDecode; if (frame != null) { const string EXIF_ORIENTATION_TAG = "/app1/{ushort=0}/{ushort=274}"; ushort? orientation = null; try { // Not supported on all input types, i.e. BMP will fail here orientation = (ushort?)frame.MetadataQueryReader.TryGetMetadataByName(EXIF_ORIENTATION_TAG); //0x0112 } catch { } // If the EXIF orientation specifies that the image needs to be flipped or rotated before display, set that up to happen if (orientation.HasValue) { switch (orientation.Value) { case 1: break; // No rotation required. case 2: bitmapTransformationOptions = BitmapTransformOptions.Rotate0 | BitmapTransformOptions.FlipHorizontal; break; case 3: bitmapTransformationOptions = BitmapTransformOptions.Rotate180; break; case 4: bitmapTransformationOptions = BitmapTransformOptions.Rotate180 | BitmapTransformOptions.FlipHorizontal; break; case 5: bitmapTransformationOptions = BitmapTransformOptions.Rotate270 | BitmapTransformOptions.FlipHorizontal; break; case 6: bitmapTransformationOptions = BitmapTransformOptions.Rotate90; break; case 7: bitmapTransformationOptions = BitmapTransformOptions.Rotate90 | BitmapTransformOptions.FlipHorizontal; break; case 8: bitmapTransformationOptions = BitmapTransformOptions.Rotate270; break; } } } // Scale down larger images int sourceWidth = source.Size.Width; int sourceHeight = source.Size.Height; if (width > 0 && height > 0 && (sourceWidth > width || sourceHeight > height)) { if (sourceWidth <= height) { width = sourceWidth; } int newHeight = sourceHeight * height / sourceWidth; if (newHeight > height) { // Resize with height instead width = sourceWidth * height / sourceHeight; newHeight = height; } scaler.Initialize(source, width, newHeight, BitmapInterpolationMode.Fant); source = scaler; } // Rotate if (bitmapTransformationOptions != BitmapTransformOptions.Rotate0) { // For fast rotation a cached bitmap is needed, otherwise only per-pixel-decoding happens which makes the process extremly slow. // See https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/5ff2b52b-602f-4b22-9fb2-371539ff5ebb/hang-in-createbitmapfromwicbitmap-when-using-iwicbitmapfliprotator?forum=windowswic cachedBitmap = new Bitmap(factory, source, BitmapCreateCacheOption.CacheOnLoad); rotator.Initialize(cachedBitmap, bitmapTransformationOptions); source = rotator; } Guid formatGuid = ContainerFormatGuids.Jpeg; imageType = ImageType.Jpeg; if (usePngOutput) { formatGuid = ContainerFormatGuids.Png; imageType = ImageType.Png; } using (var encoder = new BitmapEncoder(factory, formatGuid)) { encoder.Initialize(output); using (var bitmapFrameEncode = new BitmapFrameEncode(encoder)) { // Create image encoder var wicPixelFormat = PixelFormat.FormatDontCare; bitmapFrameEncode.Initialize(); bitmapFrameEncode.SetSize(source.Size.Width, source.Size.Height); bitmapFrameEncode.SetPixelFormat(ref wicPixelFormat); bitmapFrameEncode.WriteSource(source); bitmapFrameEncode.Commit(); encoder.Commit(); } } imageData = output.ToArray(); return(true); } } catch (Exception) { //ServiceRegistration.Get<ILogger>().Warn("WICThumbnailProvider: Error loading bitmapSource from file data stream", ex); return(false); } finally { cachedBitmap?.Dispose(); } }
private void RenderThread(object obj) { var providerParam = new KinectImageProvider[1]; try { while (!this.Dispatcher.HasShutdownStarted && !this.disposed) { try { if (this.renderEvent.Wait(100)) { this.renderEvent.Reset(); if (this.disposed) { return; } using var frame = Interlocked.Exchange(ref this.lastFrame, null); if (frame != null && frame.Bitmap != null) { var frameSize = frame.Bitmap.Size; var ratio = 1d; if (this.RenderWidth > 0 && frameSize.Width > frameSize.Height) { ratio = (double)this.RenderWidth / frameSize.Width; } if (this.RenderHeight > 0 && frameSize.Height > frameSize.Width) { ratio = (double)this.RenderHeight / frameSize.Height; } ratio = ratio > 1 ? 1 : ratio; var desiredSize = new Size2((int)(frameSize.Width * ratio), (int)(frameSize.Height * ratio)); if (this.renderTarget == null || this.renderTargetDescription.Width != desiredSize.Width || this.renderTargetDescription.Height != desiredSize.Height) { this.renderTarget?.Dispose(); this.cpuRenderTarget?.Dispose(); this.CreateRenderTargets(desiredSize); } using var scale = new BitmapScaler(this.imagingFactory); scale.Initialize(frame.Bitmap, desiredSize.Width, desiredSize.Height, BitmapInterpolationMode.Linear); using var bitmap = new Bitmap(this.imagingFactory, scale, BitmapCreateCacheOption.NoCache); using var bitmapLock = bitmap.Lock(BitmapLockFlags.Read); DataBox imageDataBox = new DataBox(bitmapLock.Data.DataPointer, bitmapLock.Data.Pitch, bitmapLock.Data.Pitch * bitmapLock.Size.Height); lock (d3dDevice) { if (!this.d3dDevice.IsDisposed) { d3dDevice.ImmediateContext.UpdateSubresource(imageDataBox, this.cpuRenderTarget); d3dDevice.ImmediateContext.CopyResource(this.cpuRenderTarget, this.renderTarget); d3dDevice.ImmediateContext.Flush(); } } if (!this.Dispatcher.HasShutdownStarted && !this.disposed) { providerParam[0] = frame.Provider; this.Dispatcher.Invoke((InvokeRenderWithProvider)this.RequestRenderForProvider, providerParam); } } } } catch (Exception e) when(!(e is OperationCanceledException)) { } } } catch (OperationCanceledException) { } }
/// <summary> /// Function to read multiple frames from a decoder that supports multiple frames. /// </summary> /// <param name="wic">WIC interface.</param> /// <param name="data">Image data to populate.</param> /// <param name="decoder">Decoder for the image.</param> private void ReadFrames(GorgonWICImage wic, GorgonImageData data, BitmapDecoder decoder) { Guid bestPixelFormat = wic.GetGUID(data.Settings.Format); // Find the best fit pixel format. if (bestPixelFormat == Guid.Empty) { throw new IOException(string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, data.Settings.Format)); } // Use the image array as the frames. int arrayCount = _actualArrayCount.Min(data.Settings.ArrayCount); for (int array = 0; array < arrayCount; array++) { var buffer = data.Buffers[0, array]; // Get the frame data. using (var frame = decoder.GetFrame(array)) { IntPtr bufferPointer = buffer.Data.BasePointer; Guid frameFormat = frame.PixelFormat; int frameWidth = frame.Size.Width; int frameHeight = frame.Size.Height; var frameOffset = GetFrameOffset(frame); // Calculate the pointer offset if we have an offset from the frame. Only offset if we're clipping the image though. if (((frameOffset.Y != 0) || (frameOffset.X != 0)) && (Clip)) { bufferPointer = buffer.Data.BasePointer + (frameOffset.Y * buffer.PitchInformation.RowPitch) + (frameOffset.X * (buffer.PitchInformation.RowPitch / buffer.Width)); } // Confirm that we actually need to perform clipping. bool needsSizeAdjust = (frameWidth + frameOffset.X > data.Settings.Width) || (frameHeight + frameOffset.Y > data.Settings.Height); // If the formats match, then we don't need to do conversion. if (bestPixelFormat == frameFormat) { // If the width and height are the same then we can just do a straight copy into the buffer. if (((frameWidth == data.Settings.Width) && (frameHeight == data.Settings.Height)) || ((!needsSizeAdjust) && (Clip))) { frame.CopyPixels(buffer.PitchInformation.RowPitch, bufferPointer, buffer.PitchInformation.SlicePitch); continue; } // We need to scale the image up/down to the size of our image data. if (!Clip) { using (var scaler = new BitmapScaler(wic.Factory)) { scaler.Initialize(frame, data.Settings.Width, data.Settings.Height, (BitmapInterpolationMode)Filter); scaler.CopyPixels(buffer.PitchInformation.RowPitch, bufferPointer, buffer.PitchInformation.SlicePitch); } continue; } using (var clipper = new BitmapClipper(wic.Factory)) { clipper.Initialize(frame, new Rectangle(0, 0, data.Settings.Width, data.Settings.Height)); clipper.CopyPixels(buffer.PitchInformation.RowPitch, bufferPointer, buffer.PitchInformation.SlicePitch); } continue; } // Poop. We need to convert this image. using (var converter = new FormatConverter(wic.Factory)) { converter.Initialize(frame, bestPixelFormat, (BitmapDitherType)Dithering, null, 0.0, BitmapPaletteType.Custom); if (((frameWidth == data.Settings.Width) && (frameHeight == data.Settings.Height)) || ((!needsSizeAdjust) && (Clip))) { converter.CopyPixels(buffer.PitchInformation.RowPitch, bufferPointer, buffer.PitchInformation.SlicePitch); continue; } // And we need to scale the image. if (!Clip) { using (var scaler = new BitmapScaler(wic.Factory)) { scaler.Initialize(converter, data.Settings.Width, data.Settings.Height, (BitmapInterpolationMode)Filter); scaler.CopyPixels(buffer.PitchInformation.RowPitch, bufferPointer, buffer.PitchInformation.SlicePitch); } continue; } using (var clipper = new BitmapClipper(wic.Factory)) { clipper.Initialize(frame, new Rectangle(0, 0, data.Settings.Width, data.Settings.Height)); clipper.CopyPixels(buffer.PitchInformation.RowPitch, bufferPointer, buffer.PitchInformation.SlicePitch); } } } } }
/// <summary> /// 從WIC Frame建立貼圖資源(非DDS) /// </summary> /// <param name="d3dContext">If a Direct3D 11 device context is provided and the current device supports it for the given pixel format, it will auto-generate mipmaps.</param> private static Result CreateWICTexture(Device device, DeviceContext d3dContext, BitmapFrameDecode frame, int maxsize, ResourceUsage usage, BindFlags bind, CpuAccessFlags cpuAccess, ResourceOptionFlags option, LoadFlags load, out Resource texture, out ShaderResourceView textureView) { texture = null; textureView = null; if (frame.Size.Width <= 0 || frame.Size.Height <= 0) { return(Result.InvalidArg); } if (maxsize == 0) { switch (device.FeatureLevel) { case FeatureLevel.Level_9_1: case FeatureLevel.Level_9_2: maxsize = 2048 /*D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; break; case FeatureLevel.Level_9_3: maxsize = 4096 /*D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; break; case FeatureLevel.Level_10_0: case FeatureLevel.Level_10_1: maxsize = 8192 /*D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; break; default: maxsize = Resource.MaximumTexture2DSize; /*D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION*/ break; } } Size2 frameSize = frame.Size; Size2 targetSize; if (frameSize.Width > maxsize || frameSize.Height > maxsize) { double ratio = Convert.ToDouble(frameSize.Height) / Convert.ToDouble(frameSize.Width); if (frameSize.Width > frameSize.Height) { targetSize.Width = maxsize; targetSize.Height = Math.Max(1, Convert.ToInt32(maxsize * ratio)); } else { targetSize.Height = maxsize; targetSize.Width = Math.Max(1, Convert.ToInt32(maxsize / ratio)); } } else { targetSize = frameSize; } #region Determine format Guid sourceFormat = frame.PixelFormat; Guid targetFormat = sourceFormat; DXGI.Format format = sourceFormat.ConvertWICToDXGIFormat(); int bpp = 0; if (format == DXGI.Format.Unknown) { if (sourceFormat == PixelFormat.Format96bppRGBFixedPoint) { if (WIC2) { targetFormat = PixelFormat.Format96bppRGBFloat; format = DXGI.Format.R32G32B32_Float; bpp = 96; } else { targetFormat = PixelFormat.Format128bppRGBAFloat; format = DXGI.Format.R32G32B32A32_Float; bpp = 128; } } else { targetFormat = sourceFormat.ConvertToNearest(); format = targetFormat.ConvertWICToDXGIFormat(); bpp = PixelFormat.GetBitsPerPixel(targetFormat); } if (format == DXGI.Format.Unknown) { return(Result.GetResultFromWin32Error(unchecked ((int)0x80070032))); } } else { bpp = PixelFormat.GetBitsPerPixel(sourceFormat); } if (format == DXGI.Format.R32G32B32_Float && d3dContext != null) { // Special case test for optional device support for autogen mipchains for R32G32B32_FLOAT var formatSupport = device.CheckFormatSupport(format); if (!formatSupport.HasFlag(FormatSupport.MipAutogen)) { targetFormat = PixelFormat.Format128bppRGBAFloat; format = DXGI.Format.R32G32B32A32_Float; bpp = 128; } } if (bpp == 0) { return(Result.Fail); } if (load.HasFlag(LoadFlags.ForceSrgb)) { format = format.MakeSRgb(); } else if (!load.HasFlag(LoadFlags.ignoreSrgb)) { bool sRGB = false; try { var metareader = frame.MetadataQueryReader; var containerFormat = metareader.ContainerFormat; if (containerFormat == ContainerFormatGuids.Png) { // Check for sRGB chunk if (metareader.TryGetMetadataByName("/sRGB/RenderingIntent", out var value) == Result.Ok) { sRGB = true; } } else if (metareader.TryGetMetadataByName("System.Image.ColorSpace", out var value) == Result.Ok) { sRGB = true; } if (sRGB) { format = format.MakeSRgb(); } } catch (SharpDXException) { // BMP, ICO are not supported. } } // Verify our target format is supported by the current device var support = device.CheckFormatSupport(format); if (!support.HasFlag(FormatSupport.Texture2D)) { targetFormat = PixelFormat.Format32bppRGBA; format = DXGI.Format.R8G8B8A8_UNorm; bpp = 32; } #endregion int stride = (targetSize.Width * bpp + 7) / 8; // round int imageSize = stride * targetSize.Height; IntPtr temp = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(imageSize); if (sourceFormat == targetFormat && frameSize == targetSize) // 不需要格式轉換 且 不需要改變大小 { frame.CopyPixels(stride, new DataPointer(temp, imageSize)); } else if (frameSize == targetSize) // 需要格式轉換 { using (var factory = new ImagingFactory2()) using (var coverter = new FormatConverter(factory)) { if (coverter.CanConvert(sourceFormat, targetFormat)) { coverter.Initialize(frame, targetFormat, BitmapDitherType.ErrorDiffusion, null, 0, BitmapPaletteType.MedianCut); coverter.CopyPixels(stride, new DataPointer(temp, imageSize)); } else { return(Result.UnexpectedFailure); } } } else if (sourceFormat == targetFormat) // 需要改變大小 { using (var factory = new ImagingFactory2()) using (var scaler = new BitmapScaler(factory)) { scaler.Initialize(frame, targetSize.Width, targetSize.Height, BitmapInterpolationMode.Fant); var pfScaler = scaler.PixelFormat; if (targetFormat == pfScaler) { scaler.CopyPixels(stride, new DataPointer(temp, imageSize)); } } } else // 需要格式轉換 且 需要改變大小 { using (var factory = new ImagingFactory2()) using (var scaler = new BitmapScaler(factory)) using (var coverter = new FormatConverter(factory)) { scaler.Initialize(frame, targetSize.Width, targetSize.Height, BitmapInterpolationMode.Fant); var pfScaler = scaler.PixelFormat; if (coverter.CanConvert(pfScaler, targetFormat)) { coverter.Initialize(scaler, targetFormat, BitmapDitherType.ErrorDiffusion, null, 0, BitmapPaletteType.MedianCut); coverter.CopyPixels(stride, new DataPointer(temp, imageSize)); } else { return(Result.UnexpectedFailure); } } } var autogen = false; if (d3dContext != null) { var formatSupport = device.CheckFormatSupport(format); if (formatSupport.HasFlag(FormatSupport.MipAutogen)) { autogen = true; } } var texture2DDescription = new Texture2DDescription() { Width = targetSize.Width, Height = targetSize.Height, MipLevels = autogen ? 0 : 1, ArraySize = 1, Format = format, SampleDescription = new DXGI.SampleDescription(1, 0), Usage = usage, CpuAccessFlags = cpuAccess, }; if (autogen) { texture2DDescription.BindFlags = bind | BindFlags.RenderTarget; texture2DDescription.OptionFlags = option | ResourceOptionFlags.GenerateMipMaps; } else { texture2DDescription.BindFlags = bind; texture2DDescription.OptionFlags = option; } Result result = Result.Ok; // 建立Texture2D !!! try { if (autogen) { texture = new Texture2D(device, texture2DDescription); } else { texture = new Texture2D(device, texture2DDescription, new DataBox[] { new DataBox(temp, stride, imageSize) }); } } catch (SharpDXException e) { System.Diagnostics.Debug.WriteLine(e.ToString()); result = Result.Fail; } if (result.Success) { var SRVDesc = new ShaderResourceViewDescription() { Format = format, Dimension = ShaderResourceViewDimension.Texture2D, Texture2D = new ShaderResourceViewDescription.Texture2DResource() { MipLevels = autogen ? -1 : 1 }, }; try { textureView = new ShaderResourceView(device, texture, SRVDesc); if (autogen) { DataBox data = new DataBox(temp, stride, imageSize); d3dContext.UpdateSubresource(data, texture); d3dContext.GenerateMips(textureView); } } catch (Exception e) { System.Diagnostics.Debug.WriteLine(e.ToString()); Utilities.Dispose(ref texture); result = Result.Fail; } } // 釋放 Unmanaged 資源 System.Runtime.InteropServices.Marshal.FreeCoTaskMem(temp); return(result); }
private void displayFileDetails(DATFileEntry entry) { Text = baseTitle + " - " + entry.Filename; savePNGButton.Visible = false; savePNGSButton.Visible = false; currentExportBitmap = null; currentExportBitmaps = null; switch (entry.Type) { case "MAP": MAPFile map = new MAPFile(entry); if (map.Error != "") { MessageBox.Show(map.Error, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Palette palette = Palette.Default; Bitmap mapBitmap = null; // find matching ICO tileset and PCC for palette if (entry.Filename.StartsWith("W")) { string baseName = entry.Filename.Substring(0, 2); if (container.Entries.ContainsKey(baseName + ".ICO")) { palette = getPaletteFrom(baseName + ".PCC"); if (palette == null) { palette = Palette.Default; } else if (baseName != "W2") { addW2Palette(palette); } ICOFile icoFile = new ICOFile(container.Entries[baseName + ".ICO"], palette); int scale = 1; mapBitmap = MAPPainter.Paint(map, icoFile, scale); currentExportBitmap = scale == 1 ? mapBitmap : MAPPainter.Paint(map, icoFile, 1); } } imgPictureBox.Image = mapBitmap; setPaletteImage(palette); log($"MAP loaded: name={entry.Filename}, width={map.Width}, height={map.Height}, palette={palette.Name}"); break; case "ARE": AREFile area = new AREFile(entry); if (area.Error != "") { MessageBox.Show(area.Error, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } //imgPictureBox.Image = BitmapScaler.PixelScale(, 3); //palettePictureBox.Image = BitmapScaler.PixelScale(Palette.ToBitmap(Palette.Default), 6); break; case "BOB": string name = Path.GetFileNameWithoutExtension(entry.Filename); if (container.Entries.ContainsKey(name + ".PCC")) { palette = getPaletteFrom(name + ".PCC"); } else if (name.Length == 1) { palette = getPaletteFrom("ANTS.PCC"); // the ants have names like A.BOB to O.BOB } else { palette = getPaletteFrom("W2.PCC"); palette.Colors[0] = Color.Black; palette.Name += " (mod)"; } BOBFile b = new BOBFile(entry, palette); if (b.Error != "") { MessageBox.Show(b.Error, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } log($"BOB contains {b.Elements.Count} images"); currentExportBitmaps = b.Elements.ToArray(); currentExportBitmap = BOBPainter.MakeSheet(b); imgPictureBox.Image = BitmapScaler.PixelScale(currentExportBitmap, 3); setPaletteImage(palette); break; case "ICO": // tileset / spritesheet string world = entry.Filename.Contains("W1") ? "W1" : (entry.Filename.Contains("W2") ? "W2" : "W3"); palette = getPaletteFrom(world + ".PCC"); if (palette == null) { palette = Palette.Default; } else if (world != "W2") { addW2Palette(palette); } ICOFile ico = new ICOFile(entry, palette); if (ico.Error != "") { MessageBox.Show("Failed to load ICO, sorry!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } log($"ICO contains {ico.Bitmaps.Length} tiles"); currentExportBitmaps = ico.Bitmaps; currentExportBitmap = ICOPainter.TileSetFromBitmaps(ico.Bitmaps); imgPictureBox.Image = BitmapScaler.PixelScale(currentExportBitmap, 3); setPaletteImage(palette); break; case "PCC": // these are actually PCX files, version 5, encoded, 8 bits per pixel PCXFile pcx = new PCXFile(); if (!pcx.Load(entry.Data)) { MessageBox.Show(pcx.Error, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } currentExportBitmap = pcx.Bitmap; imgPictureBox.Image = BitmapScaler.PixelScale(pcx.Bitmap, 4); setPaletteImage(Palette.ToBitmap(pcx.Palette), "own"); log($"PCC loaded: name={entry.Filename}, width={pcx.Bitmap.Width}, height={pcx.Bitmap.Height}, palette=own"); break; default: break; } if (currentExportBitmap != null) { savePNGButton.Visible = true; } if (currentExportBitmaps != null && currentExportBitmaps.Length > 0) { savePNGSButton.Visible = true; } }
private void setPaletteImage(Bitmap bmp, string name) { palettePictureBox.Image = BitmapScaler.PixelScale(bmp, 8); paletteNameLabel.Text = name; }