public static void CopyRegion(Bitmap source, Bitmap target, Rectangle srcRect, Rectangle destRect) { FastBitmap fastTarget = new FastBitmap(target); using (fastTarget.Lock()) { fastTarget.CopyRegion(source, srcRect, destRect); } }
/// <summary> /// Returns an image that represents the slice of another image /// </summary> /// <param name="original">The original image to get the slice of</param> /// <param name="sliceSize">The size of the sliced image</param> /// <param name="bounds">The bounds of the original image to slice</param> /// <param name="origin">A rectangle that represents the rectangle the image will take in the sliced image</param> /// <returns>A slice of the original image that fits within the specified bounds</returns> public static Bitmap SliceImage(Bitmap original, Size sliceSize, Rectangle bounds, Rectangle origin = new Rectangle()) { Bitmap ret = new Bitmap(sliceSize.Width, sliceSize.Height, original.PixelFormat); FastBitmap.CopyRegion(original, ret, bounds, origin); return(ret); }
public void TestSameBitmapCopyRegionException() { Bitmap bitmap = new Bitmap(64, 64); Rectangle sourceRectangle = new Rectangle(0, 0, 64, 64); Rectangle targetRectangle = new Rectangle(0, 0, 64, 64); FastBitmap.CopyRegion(bitmap, bitmap, sourceRectangle, targetRectangle); }
public void TestClippingCopyRegion() { var canvasBitmap = new Bitmap(64, 64); var copyBitmap = GenerateRandomBitmap(32, 32); var sourceRectangle = new Rectangle(-5, 5, 32, 32); var targetRectangle = new Rectangle(40, 9, 23, 48); FastBitmap.CopyRegion(copyBitmap, canvasBitmap, sourceRectangle, targetRectangle); AssertCopyRegionEquals(canvasBitmap, copyBitmap, targetRectangle, sourceRectangle); }
public void TestInvalidCopyRegion() { Bitmap canvasBitmap = new Bitmap(64, 64); Bitmap copyBitmap = GenerateRandomBitmap(32, 32); Rectangle sourceRectangle = new Rectangle(0, 0, -1, 32); Rectangle targetRectangle = new Rectangle(0, 0, 23, 48); FastBitmap.CopyRegion(copyBitmap, canvasBitmap, sourceRectangle, targetRectangle); AssertCopyRegionEquals(canvasBitmap, copyBitmap, targetRectangle, sourceRectangle); }
public void TestInvalidCopyRegion() { var canvasBitmap = new Bitmap(64, 64); var copyBitmap = GenerateRainbowBitmap(32, 32); var sourceRectangle = new Rectangle(0, 0, -1, 32); var targetRectangle = new Rectangle(0, 0, 23, 48); FastBitmap.CopyRegion(copyBitmap, canvasBitmap, sourceRectangle, targetRectangle); BitmapSnapshot.Snapshot(canvasBitmap, TestContext); }
public void TestOutOfBoundsCopyRegion() { var canvasBitmap = new Bitmap(64, 64); var copyBitmap = GenerateRandomBitmap(32, 32); var sourceRectangle = new Rectangle(32, 0, 32, 32); var targetRectangle = new Rectangle(0, 0, 23, 48); FastBitmap.CopyRegion(copyBitmap, canvasBitmap, sourceRectangle, targetRectangle); AssertCopyRegionEquals(canvasBitmap, copyBitmap, targetRectangle, sourceRectangle); }
public void TestSequentialCopyRegion() { Bitmap bitmap1 = new Bitmap(64, 64); Bitmap bitmap2 = new Bitmap(64, 64); Bitmap bitmap3 = new Bitmap(64, 64); Bitmap bitmap4 = new Bitmap(64, 64); Rectangle region = new Rectangle(0, 0, 64, 64); FastBitmap.CopyRegion(bitmap1, bitmap2, region, region); FastBitmap.CopyRegion(bitmap3, bitmap4, region, region); FastBitmap.CopyRegion(bitmap1, bitmap3, region, region); FastBitmap.CopyRegion(bitmap4, bitmap2, region, region); }
public static Dictionary <string, Bitmap> SplitTexture(PsbDictionary tex, PsbSpec spec) { var icon = (PsbDictionary)tex["icon"]; var texture = (PsbDictionary)tex["texture"]; //var mipmap = (PsbDictionary)texture["mipMap"]; //TODO: Mipmap? Dictionary <string, Bitmap> textures = new Dictionary <string, Bitmap>(icon.Count); var pixel = texture[Consts.ResourceKey]; if (pixel == null || !(pixel is PsbResource pixelRes)) { throw new PsbBadFormatException(PsbBadFormatReason.Resources, "External Texture PSB is not supported. Please Link textures into PSB."); return(textures); } var md = PsbResHelper.GenerateImageMetadata(texture, pixelRes); md.Spec = spec; //Important Bitmap bmp = md.ToImage(); foreach (var iconPair in icon) { var info = (PsbDictionary)iconPair.Value; var width = (int)(PsbNumber)info["width"]; var height = (int)(PsbNumber)info["height"]; var top = (int)(PsbNumber)info["top"]; var left = (int)(PsbNumber)info["left"]; Bitmap b = new Bitmap(width, height, PixelFormat.Format32bppArgb); #if USE_FASTBITMAP using (FastBitmap f = b.FastLock()) { f.CopyRegion(bmp, new Rectangle(left, top, width, height), new Rectangle(0, 0, b.Width, b.Height)); } #else Graphics g = Graphics.FromImage(b); //g.InterpolationMode = InterpolationMode.NearestNeighbor; //g.PixelOffsetMode = PixelOffsetMode.Half; g.DrawImage(bmp, new Rectangle(0, 0, b.Width, b.Height), new Rectangle(left, top, width, height), GraphicsUnit.Pixel); g.Dispose(); #endif textures.Add(iconPair.Key, b); } bmp.Dispose(); return(textures); }
private void ApplyEdgeProcessFast(TextureEdgeProcess edge, FastBitmap f, Bitmap s, Node n) { if (edge == TextureEdgeProcess.Expand1Px) { if (Padding < 2) // partL expand 1px to right, partR expand 1px to left, therefore 2px needed { throw new ArgumentOutOfRangeException(nameof(edge), "Padding must > 2 when using Texture Edge Expand"); } //source: pick a slice from part; dest: put slice to atlas //top f.CopyRegion(s, new Rectangle(0, 0, s.Width, 1), new Rectangle(n.Bounds.X, n.Bounds.Y - 1, s.Width, 1)); //down f.CopyRegion(s, new Rectangle(0, s.Height - 1, s.Width, 1), new Rectangle(n.Bounds.X, n.Bounds.Y + n.Bounds.Height, s.Width, 1)); //left f.CopyRegion(s, new Rectangle(0, 0, 1, s.Height), new Rectangle(n.Bounds.X - 1, n.Bounds.Y, 1, s.Height)); //right f.CopyRegion(s, new Rectangle(s.Width - 1, 0, 1, s.Height), new Rectangle(n.Bounds.X + n.Bounds.Width, n.Bounds.Y, 1, s.Height)); } }
public void TestSlicedDestinationCopyRegion() { // Have a copy operation that goes: // // -src--- // -dest-|-----|------ // | |xxxxx| | // | |xxxxx| | // ------|-----|------ // ------- // var canvasBitmap = new Bitmap(128, 32); var copyBitmap = GenerateRainbowBitmap(32, 64); var sourceRectangle = new Rectangle(0, 0, 32, 64); var targetRectangle = new Rectangle(48, -16, 32, 64); FastBitmap.CopyRegion(copyBitmap, canvasBitmap, sourceRectangle, targetRectangle); BitmapSnapshot.Snapshot(canvasBitmap, TestContext); }
/// <summary> /// Generates an image that represents the sequential sprite strip from the specified animation. /// If the animation contains no frames, an empty 1x1 image is returned /// </summary> /// <param name="animation">The animation to generate the sprite strip image from</param> /// <returns>An image that represents the sequential sprite strip from the specified animation</returns> public Image GenerateSpriteStrip(Animation animation) { // If the frame count is 0, return an empty 1x1 image if (animation.FrameCount == 0) { return(new Bitmap(1, 1, PixelFormat.Format32bppArgb)); } // Create the image var stripBitmap = new Bitmap(animation.Width * animation.FrameCount, animation.Height); // Copy the frames into the strip bitmap now foreach (var frame in animation.Frames) { using (var composed = frame.GetComposedBitmap()) { FastBitmap.CopyRegion(composed, stripBitmap, new Rectangle(Point.Empty, frame.Size), new Rectangle(new Point(frame.Index * frame.Width, 0), frame.Size)); } } return(stripBitmap); }
public static Dictionary <string, Bitmap> SplitTexture(PsbDictionary tex, PsbSpec spec) { var icon = (PsbDictionary)tex["icon"]; var texture = (PsbDictionary)tex["texture"]; //var mipmap = (PsbDictionary)texture["mipMap"]; //TODO: Mipmap? Dictionary <string, Bitmap> textures = new Dictionary <string, Bitmap>(icon.Count); var md = PsbResCollector.GenerateMotionResMetadata(texture, (PsbResource)texture["pixel"]); md.Spec = spec; //Important Bitmap bmp = md.ToImage(); foreach (var iconPair in icon) { var info = (PsbDictionary)iconPair.Value; var width = (int)(PsbNumber)info["width"]; var height = (int)(PsbNumber)info["height"]; var top = (int)(PsbNumber)info["top"]; var left = (int)(PsbNumber)info["left"]; Bitmap b = new Bitmap(width, height, PixelFormat.Format32bppArgb); #if USE_FASTBITMAP using (FastBitmap f = b.FastLock()) { f.CopyRegion(bmp, new Rectangle(left, top, width, height), new Rectangle(0, 0, b.Width, b.Height)); } #else Graphics g = Graphics.FromImage(b); //g.InterpolationMode = InterpolationMode.NearestNeighbor; //g.PixelOffsetMode = PixelOffsetMode.Half; g.DrawImage(bmp, new Rectangle(0, 0, b.Width, b.Height), new Rectangle(left, top, width, height), GraphicsUnit.Pixel); g.Dispose(); #endif textures.Add(iconPair.Key, b); } bmp.Dispose(); return(textures); }
public void TestSlicedDestinationCopyRegion() { // Have a copy operation that goes: // // -src--- // -dest-|-----|------ // | |xxxxx| | // | |xxxxx| | // ------|-----|------ // ------- // Bitmap canvasBitmap = new Bitmap(128, 32); Bitmap copyBitmap = GenerateRandomBitmap(32, 64); Rectangle sourceRectangle = new Rectangle(0, 0, 32, 64); Rectangle targetRectangle = new Rectangle(32, -16, 32, 64); FastBitmap.CopyRegion(copyBitmap, canvasBitmap, sourceRectangle, targetRectangle); AssertCopyRegionEquals(canvasBitmap, copyBitmap, targetRectangle, sourceRectangle); }
protected override void DrawCore(DrawArgs args) { if (_currentMap == null) { return; } // 绘制地图 args.FastBitmap.Lock(); args.FastBitmap.CopyRegion(_currentMap.Bitmap, _currentRectangle, new Rectangle(0, 0, args.Width, args.Height)); args.FastBitmap.Unlock(); //绘制遮罩层 FastBitmap fastBitmap = new FastBitmap(args.CurrentCanvas.Normal); fastBitmap.Lock(); fastBitmap.CopyRegion(_currentMap.MaskBitmap, _currentRectangle, new Rectangle(0, 0, args.Width, args.Height)); fastBitmap.Unlock(); //设置世界坐标 args.WorldPoint = new Point(_currentRectangle.X, _currentRectangle.Y); }
protected override void DrawCore(DrawArgs args) { //空值检测 if (_frame == null || _header == null || _currentPlayer == null) { return; } //计算显示位置 var currentPlayerX = _currentPlayer.At.X; var currentPlayerY = _currentPlayer.At.Y; var worldPointX = args.WorldPoint.X; var worldPointY = args.WorldPoint.Y; var sourceRect = new Rectangle(0, 0, _header.Width, _header.Height); int targX = currentPlayerX - worldPointX - _header.KeyX; int targY = currentPlayerY - worldPointY - _header.KeyY; var targetRect = new Rectangle(targX, targY, _header.Width, _header.Height); //将图像复制到画布 : args.FastBitmap FastBitmap fastBitmap = args.FastBitmap; fastBitmap.Lock(); fastBitmap.CopyRegion(_frame.Bitmap, sourceRect, targetRect); fastBitmap.Unlock(); }
/// <summary> /// Split textures into parts and save to files /// </summary> /// <param name="psb">PSB</param> /// <param name="path">Save directory</param> /// <param name="option">Save option</param> /// <param name="imageFormat">Save format</param> /// <param name="pixelFormat">When save to PSB special formats, specific pixel format to use</param> public static void SplitTextureToFiles(this PSB psb, string path, PsbImageOption option = PsbImageOption.Extract, PsbImageFormat imageFormat = PsbImageFormat.Png, PsbPixelFormat pixelFormat = PsbPixelFormat.None) { if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } var source = (PsbDictionary)psb.Objects["source"]; foreach (var texPair in source) { if (!(texPair.Value is PsbDictionary tex)) { continue; } var name = texPair.Key; if (!Directory.Exists(Path.Combine(path, name))) { Directory.CreateDirectory(Path.Combine(path, name)); } var icon = (PsbDictionary)tex["icon"]; var texture = (PsbDictionary)tex["texture"]; //var mipmap = (PsbDictionary)texture["mipMap"]; //TODO: Mipmap? var md = PsbResCollector.GenerateMotionResMetadata(texture, (PsbResource)texture["pixel"]); md.Spec = psb.Platform; //Important Bitmap bmp = md.ToImage(); foreach (var iconPair in icon) { var savePath = Path.Combine(path, name, iconPair.Key); var info = (PsbDictionary)iconPair.Value; var width = (int)(PsbNumber)info["width"]; var height = (int)(PsbNumber)info["height"]; var top = (int)(PsbNumber)info["top"]; var left = (int)(PsbNumber)info["left"]; var attr = (int)(PsbNumber)info["attr"]; Bitmap b = new Bitmap(width, height, PixelFormat.Format32bppArgb); #if USE_FASTBITMAP using (FastBitmap f = b.FastLock()) { f.CopyRegion(bmp, new Rectangle(left, top, width, height), new Rectangle(0, 0, b.Width, b.Height)); } #else Graphics g = Graphics.FromImage(b); //g.InterpolationMode = InterpolationMode.NearestNeighbor; //g.PixelOffsetMode = PixelOffsetMode.Half; g.DrawImage(bmp, new Rectangle(0, 0, b.Width, b.Height), new Rectangle(left, top, width, height), GraphicsUnit.Pixel); g.Dispose(); #endif switch (option) { case PsbImageOption.Decompress: File.WriteAllBytes(savePath + ".raw", RL.GetPixelBytesFromImage(b, pixelFormat)); break; case PsbImageOption.Compress: File.WriteAllBytes(savePath + ".rl", RL.CompressImage(b, pixelFormat)); break; case PsbImageOption.Original: case PsbImageOption.Extract: default: switch (imageFormat) { case PsbImageFormat.Bmp: b.Save(savePath + ".bmp", ImageFormat.Bmp); break; case PsbImageFormat.Png: default: b.Save(savePath + ".png", ImageFormat.Png); //b.Save(savePath + $"_{attr}.png", ImageFormat.Png); break; } break; } } bmp.Dispose(); } }
public void RepaintScreenLines(int from, int to) { var r = new Rectangle(0, from, SIZE, to - from); FastBitmap.CopyRegion(_shadowImage, _primImage, r, r); }
/// <summary> /// 加载资源 /// </summary> public override void Load() { if (_loaded) { return; } Logger.Info($"Begin Load Map : {_fileName}"); try { var buffer4 = new byte[4]; using (var fs = new FileStream(_fileName, FileMode.Open)) { //1.Read Header //1.1.Read Width Height fs.Read(buffer4, 0, 4); _flag = BitConverter.ToString(buffer4); fs.Read(buffer4, 0, 4); _width = BitConverter.ToInt32(buffer4, 0); MaxX = _width - Global.Width; fs.Read(buffer4, 0, 4); _height = BitConverter.ToInt32(buffer4, 0); MaxY = _height - Global.Height; _unitColumns = (int)Math.Ceiling((double)Width / Global.ImageWidthPerMapUnit); _unitRows = (int)Math.Ceiling((double)Height / Global.ImageHeightPerMapUnit); _unitSize = _unitColumns * _unitRows; _unitOffsets = new int[_unitSize]; //_units = new Unit[_unitSize]; Logger.Info($"Flag(302E314D):{_flag},Width:{Width}" + $",Height:{Height},Unit Columns:{_unitColumns}" + $",Unit Rows:{_unitRows},Unit Size:{_unitSize}"); //1.2.Read Unit Indexes for (var i = 0; i < _unitSize; i++) { fs.Read(buffer4, 0, 4); _unitOffsets[i] = BitConverter.ToInt32(buffer4, 0); //Logger.Debug($"Unit:{i},Offset:{_unitOffsets[i]}"); } //1.3.Read Mask Header fs.Read(buffer4, 0, 4); _maskFlag = BitConverter.ToString(buffer4); fs.Read(buffer4, 0, 4); _maskSize = BitConverter.ToInt32(buffer4, 0); _maskOffsets = new int[_maskSize]; //_masks = new Mask[_maskSize]; Logger.Info($"Mask Head Flag(70030000):{_maskFlag},Mask Size:{_maskSize}"); for (var i = 0; i < _maskSize; i++) { fs.Read(buffer4, 0, 4); _maskOffsets[i] = BitConverter.ToInt32(buffer4, 0); } Bitmap = new Bitmap(Width, Height); MaskBitmap = new Bitmap(Width, Height); Grid = new byte[_unitRows * Global.CellHeightPerMapUnit, _unitColumns *Global.CellWidthPerMapUnit]; _masks = new byte[Height, Width]; fs.Seek(0, SeekOrigin.Begin); //2.Read Map Image And Grid Logger.Info("Begin Read Map Image And Grid"); using (ImageFactory factory = new ImageFactory()) { for (var rowIndex = 0; rowIndex < _unitRows; rowIndex++) { for (var colIndex = 0; colIndex < _unitColumns; colIndex++) { var index = colIndex + _unitColumns * rowIndex; var unit = ReadUnit(fs, _unitOffsets[index]); if (!unit.Decoded) { continue; } // 复制Cell for (int i = 0; i < unit.Cell.Data.Length; i++) { int x = i / Global.CellWidthPerMapUnit; int y = i % Global.CellWidthPerMapUnit; int indexX = x + Global.CellHeightPerMapUnit * rowIndex; int indexY = y + Global.CellWidthPerMapUnit * colIndex; Grid[indexX, indexY] = (byte)(unit.Cell.Data[i] == 0 ? 1 : 0); } // 复制Image if (factory.Load(unit.RealImage) .Image is Bitmap unitBitmap) { FastBitmap.CopyRegion(unitBitmap, Bitmap, new Rectangle(0, 0, unitBitmap.Width, unitBitmap.Height), new Rectangle(colIndex * 320, rowIndex * 240, unitBitmap.Width , unitBitmap.Height)); } } } } if (Global.ShowMapMask) { Logger.Info("End Read Map Image And Grid"); //3.Read Mask FastBitmap bitmap = new FastBitmap(MaskBitmap); bitmap.Lock(); Logger.Info("Begin Read Mask"); for (int i = 0; i < _maskSize; i++) { var mask = ReadMask(fs, _maskOffsets[i]); for (int h = 0; h < mask.Height; h++) { for (int w = 0; w < mask.Width; w++) { int maskIndex = (h * mask.AlignWidth + w) * 2; //单位:位 byte maskValue1 = mask.DecodedData[maskIndex / 8]; //定位到字节 var maskValue = (byte)(maskValue1 >> (maskIndex % 8)); //定位到位 var index0 = mask.StartY + h; var index1 = mask.StartX + w; byte value = (byte)((maskValue & 3) == 3 ? 1 : 0); _masks[index0, index1] = value; if (value == 1) { var pixel = Bitmap.GetPixel(index1, index0); bitmap.SetPixel(index1, index0, pixel); } } } } bitmap.Unlock(); Logger.Info("End Read Mask"); } } _loaded = true; } catch (Exception e) { Logger.Error($"Error In Load Map : {_fileName}", e); throw; } Logger.Info($"End Load Map : {_fileName}"); }
/// <summary> /// Redoes this task /// </summary> public override void Redo() { FastBitmap.CopyRegion(_newBitmap, _targetBitmap, new Rectangle(0, 0, _newBitmap.Width, _newBitmap.Height), new Rectangle(_drawPoint, new Size(_targetBitmap.Width, _targetBitmap.Height))); }