public void Update(Int32Rect?rect = null, Palette palette = null, TileSet tileSet = null, bool?withInteractionOverlay = null) { _palette = palette ?? _palette; _tileSet = tileSet ?? _tileSet; _withInteractionOverlay = withInteractionOverlay ?? _withInteractionOverlay; if (rect.HasValue) { Update(rect.Value); } else { Update(); } }
public unsafe void Invalidate(Int32Rect?dirtyRect) { SecurityHelper.DemandUnmanagedCode(); Int32Rect value; if (dirtyRect.HasValue) { value = dirtyRect.Value; value.ValidateForDirtyRect("dirtyRect", _pixelWidth, _pixelHeight); value = dirtyRect.Value; if (!value.HasArea) { return; } } WritePreamble(); if (_unmanagedSource != null) { if (base.UsableWithoutCache) { int i = 0; for (int channelCount = _duceResource.GetChannelCount(); i < channelCount; i++) { DUCE.Channel channel = _duceResource.GetChannel(i); DUCE.MILCMD_BITMAP_INVALIDATE mILCMD_BITMAP_INVALIDATE = default(DUCE.MILCMD_BITMAP_INVALIDATE); mILCMD_BITMAP_INVALIDATE.Type = MILCMD.MilCmdBitmapInvalidate; mILCMD_BITMAP_INVALIDATE.Handle = _duceResource.GetHandle(channel); bool hasValue = dirtyRect.HasValue; if (hasValue) { ref MS.Win32.NativeMethods.RECT dirtyRect2 = ref mILCMD_BITMAP_INVALIDATE.DirtyRect; value = dirtyRect.Value; dirtyRect2.left = value.X; ref MS.Win32.NativeMethods.RECT dirtyRect3 = ref mILCMD_BITMAP_INVALIDATE.DirtyRect; value = dirtyRect.Value; dirtyRect3.top = value.Y; ref MS.Win32.NativeMethods.RECT dirtyRect4 = ref mILCMD_BITMAP_INVALIDATE.DirtyRect; value = dirtyRect.Value; int x = value.X; value = dirtyRect.Value; dirtyRect4.right = x + value.Width; ref MS.Win32.NativeMethods.RECT dirtyRect5 = ref mILCMD_BITMAP_INVALIDATE.DirtyRect; value = dirtyRect.Value; int y = value.Y; value = dirtyRect.Value; dirtyRect5.bottom = y + value.Height; }
public unsafe override void CopyPixels(Int32Rect?sourceRect, int stride, IntPtr buffer, int bufferLength) { Int32Rect rect; IntPtr rectPtr; if (sourceRect.HasValue) { rect = sourceRect.Value; rectPtr = new IntPtr(&rect); } else { rectPtr = IntPtr.Zero; } _frame.CopyPixels(rectPtr, (uint)stride, buffer, (uint)bufferLength); }
/// <summary> /// 初始化精灵对象,它只能被执行一次 /// </summary> /// <param name="resName">资源名称</param> /// <param name="resType">资源类型</param> /// <param name="uri">材质的路径</param> /// <param name="cutrect">材质切割矩形</param> public void Init(string resName, ResourceType resType, Uri uri, Int32Rect?cutrect = null) { if (!this.IsInit) { this.ResourceName = resName; this.ResourceType = resType; this.SpriteBitmapImage = new BitmapImage(); this.SpriteBitmapImage.BeginInit(); this.SpriteBitmapImage.UriSource = uri; if (cutrect != null) { this.CutRect = (Int32Rect)cutrect; this.SpriteBitmapImage.SourceRect = this.CutRect; } this.SpriteBitmapImage.EndInit(); this.IsInit = true; } else { LogUtils.LogLine(String.Format("Sprite Init again: {0}", resName), "MySprite", LogLevel.Error); } }
protected override void OnMouseMove(MouseEventArgs e) { try { if (ModelView.CharacterIsolation != null && ModelView.CharacterIsolation.Output != null) { Point pos = e.GetPosition(IsolationOutput); var bmpImage = (WriteableBitmap)IsolationOutput.Source; var pixelX = (int)(pos.X * bmpImage.PixelWidth / IsolationOutput.ActualWidth); var pixelY = (int)(pos.Y * bmpImage.PixelHeight / IsolationOutput.ActualHeight); Int32Rect?zone = ModelView.CharacterIsolation.GetCurrentZone(pixelX, pixelY); DebugInformation = pixelX + "," + pixelY + " zone:" + zone; if (zone != null) { CurrentZone = new CroppedBitmap(ModelView.Original, zone.Value); } } } catch (Exception) { } base.OnMouseMove(e); }
protected override void OnMouseDown(MouseButtonEventArgs e) { try { if (ModelView.CharacterIsolation != null && ModelView.CharacterIsolation.Output != null) { Point pos = e.GetPosition(IsolationOutput); var bmpImage = (WriteableBitmap)IsolationOutput.Source; var pixelX = (int)(pos.X * bmpImage.PixelWidth / IsolationOutput.ActualWidth); var pixelY = (int)(pos.Y * bmpImage.PixelHeight / IsolationOutput.ActualHeight); Int32Rect?zone = ModelView.CharacterIsolation.GetCurrentZone(pixelX, pixelY); if (zone != null) { ModelView.RecognizeCommand.Execute(zone.Value); } } } catch (Exception) { } base.OnMouseDown(e); }
/// <summary> /// Invalidates the bitmap source. /// </summary> public void Invalidate(Int32Rect?dirtyRect) { // A null dirty rect indicates the entire bitmap should be // invalidated, while a value indicates that only a dirty rect // should be invalidated. if (dirtyRect.HasValue) { dirtyRect.Value.ValidateForDirtyRect("dirtyRect", _pixelWidth, _pixelHeight); if (!dirtyRect.Value.HasArea) { // Nothing needs done. return; } } WritePreamble(); if (_unmanagedSource != null) { if (UsableWithoutCache) { // For bitmap sources that do not require caching on the // UI thread, we can just add a dirty rect to the // CWICWrapperBitmap. The render thread will respond by // updating the affected realizations by copying from this // bitmap. Since this bitmap is not cached, it will get // the most current bits. unsafe { for (int i = 0, numChannels = _duceResource.GetChannelCount(); i < numChannels; ++i) { DUCE.Channel channel = _duceResource.GetChannel(i); DUCE.MILCMD_BITMAP_INVALIDATE data; data.Type = MILCMD.MilCmdBitmapInvalidate; data.Handle = _duceResource.GetHandle(channel); bool useDirtyRect = dirtyRect.HasValue; if (useDirtyRect) { data.DirtyRect.left = dirtyRect.Value.X; data.DirtyRect.top = dirtyRect.Value.Y; data.DirtyRect.right = dirtyRect.Value.X + dirtyRect.Value.Width; data.DirtyRect.bottom = dirtyRect.Value.Y + dirtyRect.Value.Height; } data.UseDirtyRect = (uint)(useDirtyRect ? 1 : 0); channel.SendCommand((byte *)&data, sizeof(DUCE.MILCMD_BITMAP_INVALIDATE)); } } } else { // For bitmap sources that require caching on the // UI thread, we can't just add a dirty rect to the // CWICWrapperBitmap because it will just read the cached // contents again. We really need a caching bitmap // implementation that understands dirty rects and will // update its cache. Unfortunately, today the caching // bitmap is a standard WIC implementation, and does not // support this functionality. // // For now, we just recreate the caching bitmap. Setting // _needsUpdate to true will cause BitmapSource to throw // away the old DUCECompatiblePtr, and create a new caching // bitmap to send to the render thread. Since the render // thread sees a brand new bitmap, it will copy the bits out. _needsUpdate = true; RegisterForAsyncUpdateResource(); } } WritePostscript(); }
private BitmapSource CreateImage() { ValidateParameters(); // First, we process layers which have a specific size. foreach (Layer layer in VisibleLayers) { if (layer.HasFixedSize) { layer.Process(); } } // Second, for SizeMode = Auto, we calculate the output dimensions // based on the union of all layers' (which have an explicit size) dimensions. int outputWidth, outputHeight; if (AutoSize) { Int32Rect outputDimensions = Int32Rect.Empty; foreach (Layer layer in VisibleLayers) { // Calculate dimensions of layers; the dimensions of some layers may be omitted // at design time and are then derived from layers which have a fixed size. // Only include layer in bounds calculation if the Anchor property is None. if (layer.Anchor == AnchorStyles.None) { Int32Rect?bounds = layer.Bounds; if (bounds != null) { outputDimensions = Int32RectUtility.Union(outputDimensions, bounds.Value); } } } outputWidth = outputDimensions.Width; outputHeight = outputDimensions.Height; } else { outputWidth = Width.Value; outputHeight = Height.Value; } // If at this point we don't have a valid size, return - this means that // layers without an explicit size will never force an image to be created. if (outputWidth == 0 && outputHeight == 0) { return(null); } // Second, layers which don't have explicit sizes set, we now set their sizes // based on the overall composition size, and process the layer. foreach (Layer layer in this.VisibleLayers) { if (!layer.HasFixedSize) { layer.CalculatedWidth = outputWidth; layer.CalculatedHeight = outputHeight; layer.Process(); } } // If any of the layers are not present, we don't create the image foreach (Layer layer in this.VisibleLayers) { if (layer.Bitmap == null) { return(null); } } // Calculate X and Y for layers which are anchored. foreach (Layer layer in this.VisibleLayers) { if (layer.Bitmap != null && layer.Anchor != AnchorStyles.None) { // Set X. switch (layer.Anchor) { case AnchorStyles.BottomCenter: case AnchorStyles.MiddleCenter: case AnchorStyles.TopCenter: layer.X = (outputWidth - layer.Size.Value.Width) / 2; break; case AnchorStyles.BottomLeft: case AnchorStyles.MiddleLeft: case AnchorStyles.TopLeft: layer.X = layer.AnchorPadding; break; case AnchorStyles.BottomRight: case AnchorStyles.MiddleRight: case AnchorStyles.TopRight: layer.X = outputWidth - layer.Size.Value.Width - layer.AnchorPadding; break; } // Set Y. switch (layer.Anchor) { case AnchorStyles.BottomCenter: case AnchorStyles.BottomLeft: case AnchorStyles.BottomRight: layer.Y = outputHeight - layer.Size.Value.Height - layer.AnchorPadding; break; case AnchorStyles.MiddleCenter: case AnchorStyles.MiddleLeft: case AnchorStyles.MiddleRight: layer.Y = (outputHeight - layer.Size.Value.Height) / 2; break; case AnchorStyles.TopCenter: case AnchorStyles.TopLeft: case AnchorStyles.TopRight: layer.Y = layer.AnchorPadding; break; } } } // Apply fill. DrawingVisual dv = new DrawingVisual(); DrawingContext dc = dv.RenderOpen(); // Apply fill. Fill.Apply(dc, new Rect(0, 0, outputWidth, outputHeight)); dc.Close(); // create output bitmap and lock data RenderTargetBitmap rtb = RenderTargetBitmapUtility.CreateRenderTargetBitmap(outputWidth, outputHeight); rtb.Render(dv); FastBitmap output = new FastBitmap(rtb); // Blend layers using specified blend mode. output = LayerBlender.BlendLayers(output, VisibleLayers); // Apply global filters. foreach (Filter filter in Filters) { if (filter.Enabled) { filter.ApplyFilter(output); } } // If image format doesn't support transparency, make all transparent pixels totally opaque. // Otherwise WPF wants to save them as black. if (ImageFormat == DynamicImageFormat.Bmp || ImageFormat == DynamicImageFormat.Jpeg) { output.Lock(); for (int y = 0; y < output.Height; ++y) { for (int x = 0; x < output.Width; ++x) { Color c = output[x, y]; //if (output[x, y].A == 0 && output[x, y].R == 0 && output[x, y].G == 0 && output[x, y].B == 0) output[x, y] = Color.FromArgb(255, c.R, c.G, c.B); } } output.Unlock(); } // Freeze the bitmap - this means any thread can access it, as well // as perhaps providing some performance benefit. output.InnerBitmap.Freeze(); return(output.InnerBitmap); }
/// <summary> /// Calculates a dictionary of each distinct "colour" in the BitmapSource. /// /// This function only works on 8 bit images. /// /// The dictionary is returned as < byte(Color), int(Count) > /// </summary> public static Dictionary <byte, int> GetDistinctColors(this BitmapSource bitmap, Int32Rect?area) { if (area.HasValue) { bitmap = new CroppedBitmap(bitmap, area.Value); } if (bitmap.PixelHeight != bitmap.PixelWidth) { throw new ArgumentException("Bitmap pixel height must match pixel width"); } var array = new byte[bitmap.PixelHeight * bitmap.PixelHeight]; bitmap.CopyPixels(array, bitmap.PixelWidth, 0); // Extended debug - if necessary Console.Write("."); return(array.GroupBy(b => b).ToDictionary(c => c.Key, d => d.Count())); }
unsafe private void segmentedImagesMenuItem_Click(object sender, RoutedEventArgs e) { System.Windows.Forms.FolderBrowserDialog fbd = new System.Windows.Forms.FolderBrowserDialog() { SelectedPath = "G:\\Training Sets\\new" }; var result = fbd.ShowDialog(); if (result != System.Windows.Forms.DialogResult.OK) { return; } foreach (double penWidth in new double[] { 8 }) { bool useCrop = true; bool tipsOnly = false; bool primaryOnly = false; bool lateralOnly = false; bool conflictOnly = false; bool sourceOnly = false; bool outputOriginalImages = false; //double penWidth = 10; this.SnapsToDevicePixels = true; RenderOptions.SetEdgeMode(this, EdgeMode.Aliased); string[] supportedDatasets = new string[] { "RSDH00", "RSDH01", "RSDH02", "RSDH03", "RSDH04", "RSDH06", "RSDH07", "RSDH08", "RSDH09", "RSDH10" }; List <string> tags = rootReader.FilterTags(supportedDatasets, true); Random rand = new Random(); string path = fbd.SelectedPath; string segPath = path + "\\segmentation" + penWidth; string imagePath = path + "\\images"; int runningTotal = 0; int count = 0; if (!Directory.Exists(imagePath)) { Directory.CreateDirectory(imagePath); } if (!Directory.Exists(segPath)) { Directory.CreateDirectory(segPath); } foreach (string tag in tags) { var data = rootReader.Read(tag, true); // If no image, skip if (data.Item3 == null) { continue; } SceneMetadata metadata = data.Item1; SceneInfo scene = data.Item2; byte[] imageData = data.Item3; BitmapSource currentImage; using (MemoryStream ms = new MemoryStream(imageData)) { JpegBitmapDecoder decoder = new JpegBitmapDecoder(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); // Due to what appears to be a bug in .NET, wrapping in a WBMP causes a cache refresh and fixes some image corruption currentImage = new WriteableBitmap(decoder.Frames[0]); } SolidColorBrush scb = new SolidColorBrush(Colors.White); Pen p = new Pen(Brushes.White, penWidth); p.StartLineCap = PenLineCap.Round; p.EndLineCap = PenLineCap.Round; // Obtain all root information Dictionary <String, RootInfo> plantComponents = new Dictionary <string, RootInfo>(); foreach (PlantInfo plant in scene.Plants) { foreach (RootInfo root in plant) { plantComponents.Add(root.RelativeID, root); } } // Initialise conflict data int conflictScale = 30; int conflictWidth = currentImage.PixelWidth / conflictScale; int conflictHeight = currentImage.PixelHeight / conflictScale; int[] rootCount = new int[conflictWidth * conflictHeight]; bool[] rootCounted = new bool[conflictWidth * conflictHeight]; // Crop // Find global plant bounding box double left = double.MaxValue, right = double.MinValue, top = double.MaxValue, bottom = double.MinValue; foreach (var kvp in plantComponents) { SampledSpline spline = kvp.Value.Spline as SampledSpline; if (spline == null) { continue; } Rect r = spline.BoundingBox; if (r.Left < left) { left = r.Left; } if (r.Right > right) { right = r.Right; } if (r.Top < top) { top = r.Top; } if (r.Bottom > bottom) { bottom = r.Bottom; } // If detecting conflict if (conflictOnly) { RootInfo parent = plantComponents.ContainsKey(kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))) ? plantComponents[kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))] : null; if (parent == null) { Array.Clear(rootCounted, 0, rootCounted.Length); foreach (Point splinePoint in spline.SampledPoints) { int conflictX = (int)(splinePoint.X / conflictScale); int conflictY = (int)(splinePoint.Y / conflictScale); int conflictIndex = conflictY * conflictWidth + conflictX; if (!rootCounted[conflictIndex]) { rootCount[conflictIndex]++; rootCounted[conflictIndex] = true; } } } } } // Render to drawingVisual, then image int width = currentImage.PixelWidth; int height = currentImage.PixelHeight; // Optional Crop Int32Rect?cropRectangle = null; if (useCrop) { int cropPadding = 64; int l = Math.Max(0, (int)(left - cropPadding)); int r = Math.Min(width, (int)(right + cropPadding)); int t = Math.Max(0, (int)(top - cropPadding)); int b = Math.Min(height, (int)(bottom + cropPadding)); cropRectangle = new Int32Rect(l, t, r - l, b - t); } RenderTargetBitmap rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32); DrawingVisual drawingVisual = new DrawingVisual(); DrawingContext drawingContext = drawingVisual.RenderOpen(); SolidColorBrush background = new SolidColorBrush(Colors.Black); drawingContext.DrawRectangle(Brushes.Black, null, new Rect(0, 0, width, height)); // Draw splines StreamGeometry geometry = new StreamGeometry(); using (StreamGeometryContext sgc = geometry.Open()) { foreach (var kvp in plantComponents) { SampledSpline spline = kvp.Value.Spline as SampledSpline; if (spline != null) { Point[] points = spline.SampledPoints; // Optional line from start position on parent if (sourceOnly) { // First primary source if (kvp.Value.RelativeID == "1.1") { sgc.BeginFigure(points[0], false, false); sgc.LineTo(points[0], true, true); break; } } if (tipsOnly) { if (primaryOnly) { RootInfo parent = plantComponents.ContainsKey(kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))) ? plantComponents[kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))] : null; if (parent == null) { sgc.BeginFigure(points[points.Length - 2], false, false); sgc.LineTo(points[points.Length - 1], true, true); } } else if (lateralOnly) { RootInfo parent = plantComponents.ContainsKey(kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))) ? plantComponents[kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))] : null; if (parent != null) { sgc.BeginFigure(points[points.Length - 2], false, false); sgc.LineTo(points[points.Length - 1], true, true); } } else { sgc.BeginFigure(points[points.Length - 2], false, false); sgc.LineTo(points[points.Length - 1], true, true); } } else { RootInfo parent = plantComponents.ContainsKey(kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))) ? plantComponents[kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))] : null; if (parent != null) { Point start = parent.Spline.GetPoint(kvp.Value.StartReference); sgc.BeginFigure(new Point(start.X, start.Y), false, false); sgc.LineTo(new Point(points[0].X, points[0].Y), true, true); } else { sgc.BeginFigure(new Point(points[0].X, points[0].Y), false, false); } for (int i = 1; i < points.Length; i++) { sgc.LineTo(new Point(points[i].X, points[i].Y), true, true); } } } } } if (geometry.CanFreeze) { geometry.Freeze(); } drawingContext.DrawGeometry(p.Brush, p, geometry); drawingContext.Close(); rtb.Render(drawingVisual); if (rtb.CanFreeze) { rtb.Freeze(); } // Save original file BitmapEncoder Encoder; if (outputOriginalImages) { Encoder = new PngBitmapEncoder(); using (FileStream FS = File.Open(imagePath + "\\" + count + ".png", FileMode.OpenOrCreate)) { Encoder.Frames.Add(BitmapFrame.Create(useCrop ? new CroppedBitmap(currentImage, cropRectangle.Value) : currentImage)); Encoder.Save(FS); FS.Close(); } } // Create mask from RTB int renderStride = rtb.PixelWidth * 4; byte[] renderArr = new byte[rtb.PixelWidth * rtb.PixelHeight * 4]; rtb.CopyPixels(renderArr, rtb.PixelWidth * 4, 0); WriteableBitmap mask = new WriteableBitmap(rtb.PixelWidth, rtb.PixelHeight, 96.0, 96.0, PixelFormats.Gray8, null); mask.Lock(); byte *ptr = (byte *)mask.BackBuffer.ToPointer(); int stride = mask.BackBufferStride; for (int x = 0; x < mask.PixelWidth; x++) { for (int y = 0; y < mask.PixelHeight; y++) { // Obtain red pixel as representative of gray value byte current = renderArr[y * renderStride + (x * 4) + 1]; if (current > 127) { if (conflictOnly) { int index = (y / conflictScale) * conflictWidth + (x / conflictScale); if (rootCount[index] > 1) { *(ptr + y * stride + x) = 255; } } else { *(ptr + y * stride + x) = 255; } } } } mask.AddDirtyRect(new Int32Rect(0, 0, width, height)); mask.Unlock(); BitmapSource outputMask = mask; Encoder = new PngBitmapEncoder(); using (FileStream FS = File.Open(segPath + "\\" + count.ToString("D4") + ".png", FileMode.OpenOrCreate)) { Encoder.Frames.Add(BitmapFrame.Create(useCrop ? new CroppedBitmap(outputMask, cropRectangle.Value) : outputMask)); Encoder.Save(FS); FS.Close(); } count++; runningTotal++; if (runningTotal > 20) { runningTotal -= 20; GC.Collect(); GC.WaitForPendingFinalizers(); } } } }
/// <summary> /// 从资源文件中获取图片资源并返回精灵对象 /// </summary> /// <param name="sourceName">资源名称</param> /// <param name="rtype">资源类型</param> /// <param name="cutRect">纹理切割矩</param> /// <returns>该资源的精灵</returns> private YuriSprite GetGraphicSprite(string sourceName, ResourceType rtype, Int32Rect?cutRect) { if (sourceName == String.Empty) { return(null); } YuriSprite sprite = new YuriSprite(); string DevURI, PackURI; // 处理路径 switch (rtype) { case ResourceType.Background: DevURI = GlobalConfigContext.DevURI_PA_BACKGROUND; PackURI = GlobalConfigContext.PackURI_PA_BACKGROUND; break; case ResourceType.Stand: DevURI = GlobalConfigContext.DevURI_PA_CHARASTAND; PackURI = GlobalConfigContext.PackURI_PA_CHARASTAND; break; case ResourceType.Pictures: DevURI = GlobalConfigContext.DevURI_PA_PICTURES; PackURI = GlobalConfigContext.PackURI_PA_PICTURES; break; default: return(null); } // 总是先查看是否有为封包的数据 if (this.resourceTable.ContainsKey(DevURI) && this.resourceTable[DevURI].ContainsKey(sourceName)) { // 检查缓冲 var ob = ResourceCachePool.Refer(rtype.ToString() + "->" + sourceName, ResourceCacheType.Eden); if (ob == null) { var sourceSlot = this.resourceTable[DevURI][sourceName]; ob = PackageUtils.GetObjectBytes(sourceSlot.BindingFile, sourceName, sourceSlot.Position, sourceSlot.Length); ResourceCachePool.Register(rtype.ToString() + "->" + sourceName, ob, ResourceCacheType.Eden); } MemoryStream ms = new MemoryStream(ob); sprite.Init(sourceName, rtype, ms, cutRect); } // 没有封包数据再搜索开发目录 else { // 检查缓冲 byte[] ob = ResourceCachePool.Refer(rtype.ToString() + "->" + sourceName, ResourceCacheType.Eden); if (ob == null) { string furi = IOUtils.JoinPath(GlobalConfigContext.DevURI_RT_PICTUREASSETS, DevURI, sourceName); if (File.Exists(IOUtils.ParseURItoURL(furi))) { Uri bg = new Uri(IOUtils.ParseURItoURL(furi), UriKind.RelativeOrAbsolute); ob = IOUtils.GetObjectBytes(bg); ResourceCachePool.Register(rtype.ToString() + "->" + sourceName, ob, ResourceCacheType.Eden); } else { MessageBox.Show("[错误] 资源文件不存在:" + sourceName); Director.GetInstance().GetMainRender().Shutdown(); return(null); } } MemoryStream ms = new MemoryStream(ob); sprite.Init(sourceName, rtype, ms, cutRect); } return(sprite); }
private void OnCropAreaDrawn(Int32Rect rect) { _cropArea = rect; SaveAsCommand.RaiseCanExecuteChanged(); SaveCommand.RaiseCanExecuteChanged(); }
protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); int maxX = this.HorizontalPositionConverter.GetMaxImagePosition(); int maxY = this.VerticalPositionConverter.GetMaxImagePosition(); double maxXView = this.HorizontalPositionConverter.GetMaxViewPosition(); double maxYView = this.VerticalPositionConverter.GetMaxViewPosition(); // FIXME: sorting everytime is slow. int[] xSplitPosArray = ImageViewModel.HorizontalSplitPositionBarViewModel.GetPositionArraySorted(); int[] ySplitPosArray = ImageViewModel.VerticalSplitPositionBarViewModel.GetPositionArraySorted(); // render lines Pen pen = new Pen(); pen.Brush = Brushes.Red; pen.Thickness = 1; foreach (int x in xSplitPosArray) { double xView = this.HorizontalPositionConverter.ConvertImagePositionToViewPosition(x); drawingContext.DrawLine(pen, new Point(xView, 0), new Point(xView, maxYView)); } foreach (int y in ySplitPosArray) { double yView = this.HorizontalPositionConverter.ConvertImagePositionToViewPosition(y); drawingContext.DrawLine(pen, new Point(0, yView), new Point(maxXView, yView)); } int i = 1; foreach (PointInt point in ImageViewModel.MarkedPointList) { int x = point.X; int y = point.Y; Int32Rect?markedRegion = Util.SearchRegionFromArray(x, y, xSplitPosArray, ySplitPosArray, maxX, maxY); if (markedRegion.HasValue) { double xView = this.HorizontalPositionConverter.ConvertImagePositionToViewPosition(x); double yView = this.VerticalPositionConverter.ConvertImagePositionToViewPosition(y); // marked point cursor drawingContext.DrawEllipse(Brushes.Red, null, new Point(xView, yView), 3.0, 3.0); // number FormattedText ft = new FormattedText( String.Format("({0})", i), System.Globalization.CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface("Verdana"), 16, // font size Brushes.Red); Rect rect = ImagePositionRectToViewPointRect(markedRegion.Value); drawingContext.DrawText(ft, new Point(rect.X + rect.Width / 2 - ft.Width / 2, rect.Y + rect.Height / 2 - ft.Height / 2)); // region color drawingContext.PushOpacity(0.5); drawingContext.DrawRectangle(Brushes.LightSalmon, null, rect); drawingContext.Pop(); i++; } } int curPosX = ImageViewModel.CurrentPositon.X; int curPosY = ImageViewModel.CurrentPositon.Y; // if y < 0 or x < 0, the cursor is on the vertical/horizontal bar if ((curPosY < 0 || curPosX < 0) && !(curPosX < 0 && curPosY < 0)) { if (this.ImageViewModel.ShowCursorLine) { Pen cursorLinePen = new Pen(); cursorLinePen.Brush = Brushes.Green; cursorLinePen.Thickness = 1; if (curPosX < maxX && curPosY < 0) { double xView = this.HorizontalPositionConverter.ConvertImagePositionToViewPosition(curPosX); drawingContext.DrawLine(cursorLinePen, new Point(xView, 0), new Point(xView, maxYView)); } else if (curPosX < 0 && curPosY < maxY) { double yView = this.VerticalPositionConverter.ConvertImagePositionToViewPosition(curPosY); drawingContext.DrawLine(cursorLinePen, new Point(0, yView), new Point(maxXView, yView)); } } } else { Int32Rect?cursorRegion = Util.SearchRegionFromArray( curPosX, curPosY, xSplitPosArray, ySplitPosArray, maxX, maxY); if (cursorRegion.HasValue) { drawingContext.PushOpacity(0.5); drawingContext.DrawRectangle(Brushes.LightGreen, null, ImagePositionRectToViewPointRect(cursorRegion.Value)); drawingContext.Pop(); } } }
/// <summary> /// 初始化精灵对象,它只能被执行一次 /// </summary> /// <param name="resName">资源名称</param> /// <param name="resType">资源类型</param> /// <param name="ms">材质的内存流</param> /// <param name="cutrect">材质切割矩形</param> public void Init(string resName, ResourceType resType, MemoryStream ms, Int32Rect?cutrect = null) { this.memoryStreamRef = ms; if (!this.IsInit) { this.ResourceName = resName; this.ResourceType = resType; var highPerformanceFlag = PersistContextDAO.Fetch("system_config_performance_set")?.ToString() == "Disable"; if (highPerformanceFlag || resType != ResourceType.Stand || resName.StartsWith("@") || !resName.Contains("_@")) { this.SpriteBitmapImage = new BitmapImage(); this.SpriteBitmapImage.BeginInit(); this.SpriteBitmapImage.StreamSource = ms; if (cutrect != null) { this.CutRect = (Int32Rect)cutrect; this.SpriteBitmapImage.SourceRect = this.CutRect; } this.SpriteBitmapImage.EndInit(); this.IsInit = true; // 加载Mask var rm = ResourceManager.GetInstance(); var maskPath = GlobalConfigContext.PictureMaskPrefix + resName; this.IsMaskTriggerable = rm.IsResourceExist(maskPath, ResourceType.Pictures); if (this.IsMaskTriggerable) { this.MaskSprite = rm.GetPicture(maskPath, ResourceManager.FullImageRect); } this.IsAutoAnimateable = false; } // 如果是立绘,就看是否需要加载帧动画 else { this.IsAutoAnimateable = true; var splitor = resName.LastIndexOf("."); var prefix = resName.Substring(0, splitor); var postfix = resName.Substring(splitor, resName.Length - splitor); this.AutoAnimationCount = 4; this.animationImageList = new List <BitmapImage>(); var rm = ResourceManager.GetInstance(); for (int i = 1; i <= this.AutoAnimationCount; i++) { var actualName = $"@{prefix}@{i}{postfix}"; var tSprite = rm.GetCharacterStand(actualName, ResourceManager.FullImageRect); this.animationImageList.Add(tSprite.SpriteBitmapImage); } this.autoAnimationTimer = new System.Windows.Forms.Timer { Interval = 5000 }; this.autoAnimationTimer.Tick += AutoAnimationTimer_Tick; this.autoAnimationTimer.Start(); this.SpriteBitmapImage = this.animationImageList[0]; this.IsInit = true; // fast wink when loaded try { this.AutoAnimationTimer_Tick(null, null); } catch (Exception e) { LogUtils.LogLine("fast wink failed: " + e.ToString(), "YuriSprite", LogLevel.Warning); } } } else { LogUtils.LogLine($"Sprite Init again: {resName}", "MySprite", LogLevel.Error); } }
public abstract void CopyPixels(Int32Rect?sourceRect, int stride, IntPtr buffer, int bufferLength);