如题:
源码项目:Scale9GridTestingProject.rar
我的:Scale9Image类源码:
1 using System; 2 using System.Windows; 3 using System.Windows.Controls; 4 using System.Windows.Media; 5 using System.Windows.Media.Imaging; 6 7 namespace Scale9GridTestingProject 8 { 9 public class Scale9Image : Image 10 { 11 private ImageSource _imgSrc; 12 private Int32Rect? _rect; 13 private ImageSource[] _s9gFragment; 14 private bool _bootScale9; 15 private BitmapImage _bi; 16 17 public Scale9Image() 18 : this(null, null, true) 19 { 20 } 21 22 public Scale9Image(ImageSource imgSrc, Int32Rect? rect, bool bootScale9) 23 : base() 24 { 25 _imgSrc = imgSrc; 26 _rect = rect; 27 _bootScale9 = bootScale9; 28 29 Source = _imgSrc; 30 } 31 32 public ImageSource imgSrc 33 { 34 get { return _imgSrc; } 35 set 36 { 37 if (_imgSrc != value) 38 { 39 _imgSrc = value; 40 Source = _imgSrc; 41 InvalidateVisual(); 42 } 43 } 44 } 45 public Int32Rect? rect 46 { 47 get { return _rect; } 48 set 49 { 50 if (_rect != value) 51 { 52 _rect = value; 53 InvalidateVisual(); 54 } 55 } 56 } 57 public bool bootScale9 58 { 59 get { return _bootScale9; } 60 set 61 { 62 if (_bootScale9 != value) 63 { 64 _bootScale9 = value; 65 InvalidateVisual(); 66 } 67 } 68 } 69 70 protected override void OnRender(DrawingContext dc) 71 { 72 if (_bootScale9 && _rect != null && _rect != Int32Rect.Empty) 73 { 74 OnS9GDraw(dc); 75 return; 76 } 77 78 base.OnRender(dc); 79 } 80 81 private void OnS9GDraw(DrawingContext dc) 82 { 83 if(Source == null) return; 84 85 DrawFragment(dc); 86 } 87 88 private void DrawFragment(DrawingContext dc) 89 { 90 Int32Rect r = rect.Value; 91 if (_s9gFragment == null) 92 { 93 Uri uri = new Uri(Source.ToString(), UriKind.RelativeOrAbsolute); 94 _bi = new BitmapImage(uri); 95 _s9gFragment = GetS9GImageSource(_bi, r); 96 } 97 ImageSource[] images = _s9gFragment; 98 Rect drawRect = new Rect(new Point(), new Size(r.X, r.Y)); 99 double right = _bi.PixelWidth - (r.X + r.Width); 100 double bottom = _bi.PixelHeight - (r.Y + r.Height); 101 double drawWidth = ActualWidth - r.X - right; 102 double drawHeight = ActualHeight - r.Y - bottom; 103 drawWidth = drawWidth < 0 ? 1 : drawWidth; 104 drawHeight = drawHeight < 0 ? 1 : drawHeight; 105 106 // draw actualSize with Green color, why ActualWidth and ActualHeigth is incorrect(in runtimes see it)? 107 dc.DrawRectangle(Brushes.Green, new Pen(Brushes.Blue, 1), new Rect(0, 0, ActualWidth, ActualHeight)); 108 // draw dpiSize with Red color, why Width and Height is incorrect(in runtimes see it)? 109 dc.DrawRectangle(Brushes.Red, new Pen(Brushes.Blue, 1), new Rect(0, 0, Width, Height)); 110 111 // tl 112 dc.DrawImage(images[0], drawRect); 113 // tm 114 drawRect.X += drawRect.Width; 115 drawRect.Width = drawWidth; 116 dc.DrawImage(images[1], drawRect); 117 // tr 118 drawRect.X += drawRect.Width; 119 drawRect.Width = right; 120 dc.DrawImage(images[2], drawRect); 121 122 // ml 123 drawRect.X = 0; 124 drawRect.Y = r.Y; 125 drawRect.Width = r.X; 126 drawRect.Height = drawHeight; 127 dc.DrawImage(images[3], drawRect); 128 // mm 129 drawRect.X += drawRect.Width; 130 drawRect.Width = drawWidth; 131 dc.DrawImage(images[4], drawRect); 132 // mr 133 drawRect.X += drawRect.Width; 134 drawRect.Width = right; 135 dc.DrawImage(images[5], drawRect); 136 137 // bl 138 drawRect.X = 0; 139 drawRect.Y = ActualHeight - bottom; 140 drawRect.Width = r.X; 141 drawRect.Height = bottom; 142 dc.DrawImage(images[6], drawRect); 143 // bm 144 drawRect.X += drawRect.Width; 145 drawRect.Width = drawWidth; 146 dc.DrawImage(images[7], drawRect); 147 // br 148 drawRect.X += drawRect.Width; 149 drawRect.Width = right; 150 dc.DrawImage(images[8], drawRect); 151 152 // after draw done, u can see the gap of between s9gimg fragments, why ? 153 // anybody help me~~~~ >_< ~~~~ 154 } 155 156 public static ImageSource CutImage(BitmapSource source, Int32Rect clipRect) 157 { 158 ImageSource results = null; 159 var stride = clipRect.Width * (source.Format.BitsPerPixel / 8); 160 var pixelsCount = clipRect.Width * clipRect.Height;//tileWidth * tileHeight; 161 var tileRect = new Int32Rect(0, 0, clipRect.Width, clipRect.Height); 162 163 var pixels = new int[pixelsCount]; 164 //var copyRect = new Int32Rect(col * tileWidth, row * tileHeight, tileWidth, tileHeight); 165 source.CopyPixels(clipRect, pixels, stride, 0); 166 var wb = new WriteableBitmap( 167 clipRect.Width, 168 clipRect.Height, 169 source.DpiX, 170 source.DpiY, 171 source.Format, 172 source.Palette); 173 wb.Lock(); 174 wb.WritePixels(tileRect, pixels, stride, 0); 175 wb.Unlock(); 176 177 results = wb; 178 return results; 179 } 180 181 public static ImageSource[] GetS9GImageSource(BitmapSource source, Int32Rect clipRect) 182 { 183 ImageSource[] results = new ImageSource[9]; 184 Int32Rect rect = Int32Rect.Empty; 185 int rightSideWidth = (int)(source.PixelWidth - clipRect.X - clipRect.Width); 186 //top-left 187 rect.Width = clipRect.X; 188 rect.Height = clipRect.Y; 189 results[0] = CutImage(source, rect); 190 //return results; 191 //top-middle 192 rect.X += rect.Width; 193 rect.Width = clipRect.Width; 194 results[1] = CutImage(source, rect); 195 //top-right 196 rect.X += rect.Width; 197 rect.Width = rightSideWidth; 198 results[2] = CutImage(source, rect); 199 200 //left side 201 rect = Int32Rect.Empty; 202 rect.Y = clipRect.Y; 203 rect.Width = clipRect.X; 204 rect.Height = clipRect.Height; 205 results[3] = CutImage(source, rect); 206 207 //middle 208 rect.X += rect.Width; 209 rect.Width = clipRect.Width; 210 results[4] = CutImage(source, rect); 211 212 //right side 213 rect.X += rect.Width; 214 rect.Width = rightSideWidth; 215 results[5] = CutImage(source, rect); 216 //bottom-left 217 rect = Int32Rect.Empty; 218 rect.Y = clipRect.Y + clipRect.Height; 219 // rect.X = clipRect.X; 220 rect.Height = source.PixelHeight - clipRect.Height - clipRect.Y; 221 rect.Width = clipRect.X; 222 results[6] = CutImage(source, rect); 223 224 //bottom-middle 225 rect.X += rect.Width; 226 rect.Width = clipRect.Width; 227 results[7] = CutImage(source, rect); 228 //bottom-right 229 rect.X += rect.Width; 230 rect.Width = rightSideWidth; 231 results[8] = CutImage(source, rect); 232 return results; 233 } 234 } 235 }
运行效果:
..母鸡为啥有gaps
。。。我也母鸡,所以才问呐。
而且,我把Actual的宽度,都绘制出一个纯红色背景,与实际出来的9宫格图标大小又不一样大。
这又是个问题。。。
这效果,我在实际项目使用中,又不会出现裂痕。
原因不明。逻辑我是优化过,再拿到项目中使用,但逻辑都一样;
这效果,我在实际项目使用中,又不会出现裂痕。
原因不明。逻辑我是优化过,再拿到项目中使用,但逻辑都一样;