本人业余时间开发了一个图片切割工具,非常好用,也很灵活!

特别对大型图片切割,更能体现出该软件的优势!

功能说明

可以设定切割的高度和宽度。切割线可以上下拖动,可以增加一个切割区域,可设定某个区域不参与切割。

主要技术点分析

切割区域确定

每个切割区域是一个长方形。用一个结构标识该属性。

  1. class SpliteMoveIndex
  2. {
  3. public enum EN_DIR
  4. {
  5. NON,
  6. HORIZONTAL,
  7. VERTICAL
  8. };
  9. public EN_DIR direct = EN_DIR.NON;//0 无;1 水平;2垂直
  10. public int rectIndex; //第几个rect
  11. public int lineIndex; //第几个线 1:上或左;2 下或右
  12. public int mouseX;
  13. public int mouseY;
  14.  
  15. public static SpliteMoveIndex CreateNon(int x, int y)
  16. {
  17. SpliteMoveIndex _nonIndex = new SpliteMoveIndex();
  18. _nonIndex.direct = EN_DIR.NON;
  19. _nonIndex.SetMouse(x, y);
  20. return _nonIndex;
  21. }
  22.  
  23. public SpliteMoveIndex()
  24. {
  25.  
  26. }
  27. public SpliteMoveIndex(int x, int y)
  28. {
  29. SetMouse(x, y);
  30. }
  31.  
  32. public bool IsSameLine(SpliteMoveIndex another)
  33. {
  34. return this.direct == another.direct
  35. && this.rectIndex == another.rectIndex
  36. && this.lineIndex == another.lineIndex;
  37. }
  38.  
  39. public bool IsIn()
  40. {
  41. return direct != EN_DIR.NON;
  42. }
  43. public bool IsHorIn()
  44. {
  45. return direct == EN_DIR.HORIZONTAL;
  46. }
  47. public bool IsVertIn()
  48. {
  49. return direct == EN_DIR.VERTICAL;
  50. }
  51.  
  52. public void SetMouse(int x, int y)
  53. {
  54. mouseX = x;
  55. mouseY = y;
  56. }
  57. }

SpliteRectGroup 负责组合这些长方形。当有鼠标移动时,动态调整这些长方形大小,再重画!

  1. class SpliteRectGroup
  2. {
  3. List<Rectangle> _listSplitRect = new List<Rectangle>();
  4. int _widthSrc;
  5. int _heightSrc;
  6.  
  7. SpliteMoveIndex _lastMoveIndex = new SpliteMoveIndex();
  8.  
  9. public int _defaultHitSpace = ;
  10.  
  11. int _moveAllFlagR = ;
  12. bool _isMoveAll = false;
  13.  
  14. //不参加切割的区域
  15. List<int> _listSplitRectNotUsed = new List<int>();
  16.  
  17. public void SetRect(int widthSrc, int heightSrc, int startX, int startY,
  18. int widthDest, int heightDest)
  19. {
  20. _widthSrc = widthSrc;
  21. _heightSrc = heightSrc;
  22. _listSplitRect.Clear();
  23.  
  24. GetSplitSize(_widthSrc, _heightSrc, startX, startY,
  25. widthDest, heightDest, ref _listSplitRect);
  26. }
  27.  
  28. public List<Rectangle> GetRects()
  29. {
  30. return _listSplitRect;
  31. }
  32.  
  33. public List<Rectangle> GetRectsSplit()
  34. {
  35. List<Rectangle> listShow = new List<Rectangle>();
  36.  
  37. int i = ;
  38. foreach(Rectangle rect in _listSplitRect)
  39. {
  40. if(IsRectUsed(i))
  41. {
  42. listShow.Add(rect);
  43. }
  44. i++;
  45. }
  46. return listShow;
  47. }
  48.  
  49. public int GetStartX()
  50. {
  51. if (_listSplitRect.Count == )
  52. return ;
  53. Rectangle first = _listSplitRect.First();
  54. return first.X;
  55. }
  56.  
  57. public int GetSpliteWidth()
  58. {
  59. if (_listSplitRect.Count == )
  60. return ;
  61. Rectangle first = _listSplitRect.First();
  62. return first.Width;
  63. }
  64.  
  65. public int GetSpliteTotalHeight()
  66. {
  67. if (_listSplitRect.Count == )
  68. return ;
  69. int i = ;
  70. foreach (Rectangle r in _listSplitRect)
  71. {
  72. i += r.Height;
  73. }
  74. return i;
  75. }
  76.  
  77. public void SetMoveAllFlag(bool flag)
  78. {
  79. _isMoveAll = flag;
  80. }
  81.  
  82. public bool GetMoveAllFlag()
  83. {
  84. return _isMoveAll;
  85. }
  86.  
  87. public int GetStartY()
  88. {
  89. if (_listSplitRect.Count == )
  90. return ;
  91. Rectangle first = _listSplitRect.First();
  92. return first.Y;
  93. }
  94. public void Draw(Graphics g)
  95. {
  96. SolidBrush brushRect = new SolidBrush(Color.FromArgb(, , , ));
  97. Font strfont = new Font("Verdana", );
  98. Brush strBrush = Brushes.Blue;
  99. Brush strBrushBack = Brushes.White;
  100.  
  101. //起点圆
  102. int x = GetStartX();
  103. int y = GetStartY();
  104. g.FillEllipse(brushRect, x - _moveAllFlagR, y - _moveAllFlagR, * _moveAllFlagR, * _moveAllFlagR);
  105. brushRect.Dispose();
  106. //起点信息
  107. string startInfo = string.Format("({0}:{1})",x,y);
  108. SizeF sizeF = g.MeasureString(startInfo, strfont);
  109. Point ptStart = new Point((int)(x-sizeF.Width/), (int)(y -sizeF.Height- _defaultHitSpace*) );
  110. g.FillRectangle(strBrushBack, new RectangleF(ptStart, sizeF));
  111. g.DrawString(startInfo, strfont, strBrush, ptStart);
  112.  
  113. //画方框
  114. Color backColor = Color.FromArgb(, Color.PowderBlue);
  115. HatchBrush hat1 = new HatchBrush(HatchStyle.OutlinedDiamond, Color.DarkBlue, backColor);
  116. HatchBrush hat2 = new HatchBrush(HatchStyle.OutlinedDiamond, Color.Red, backColor);
  117.  
  118. //输出提示信息
  119. Pen rectPen = Pens.Red;
  120. int i = ;
  121. int showIndex = ;
  122. string info;
  123. foreach (Rectangle rect in _listSplitRect)
  124. {
  125. i++;
  126. bool used = IsRectUsed(rect);
  127. if (used)
  128. {
  129. showIndex++;
  130. info = string.Format("{0}-({1}:{2})", showIndex, rect.Width, rect.Height);
  131. }
  132. else
  133. {
  134. info = string.Format("({0}:{1})--不参与切割", rect.Width, rect.Height);
  135. }
  136.  
  137. g.DrawRectangle(rectPen, rect);
  138. if (!used)
  139. {
  140. g.FillRectangle(hat1, rect);
  141. }
  142.  
  143. Point strStart = new Point(rect.X + , rect.Y + );
  144. sizeF = g.MeasureString(info, strfont);
  145. g.FillRectangle(strBrushBack, new RectangleF(strStart, sizeF));
  146.  
  147. g.DrawString(info, strfont, strBrush, strStart);
  148. }
  149. strfont.Dispose();
  150. hat1.Dispose();
  151. hat2.Dispose();
  152. }
  153. public bool StartPointMoveTo(int x, int y)
  154. {
  155. if (_listSplitRect.Count == )
  156. return false;
  157.  
  158. Rectangle first = _listSplitRect.First();
  159. int moveX = x - first.X;
  160. int moveY = y - first.Y;
  161.  
  162. List<Rectangle> listSplitRectNew = new List<Rectangle>();
  163. foreach (Rectangle r in _listSplitRect)
  164. {
  165. Rectangle tmp = r;
  166. tmp.Offset(moveX, moveY);
  167. listSplitRectNew.Add(tmp);
  168. }
  169.  
  170. _listSplitRect.Clear();
  171. _listSplitRect = listSplitRectNew;
  172. return true;
  173. }
  174.  
  175. public bool IsAllMove(int mouseX, int mouseY)
  176. {
  177. GraphicsPath myGraphicsPath = new GraphicsPath();
  178. myGraphicsPath.Reset();
  179. Region myRegion = new Region();
  180.  
  181. int x = GetStartX();
  182. int y = GetStartY();
  183. myGraphicsPath.AddEllipse(x - _moveAllFlagR, y - _moveAllFlagR, * _moveAllFlagR, * _moveAllFlagR);//points);
  184. myRegion.MakeEmpty();
  185. myRegion.Union(myGraphicsPath);
  186. //返回判断点是否在多边形里
  187. bool myPoint = myRegion.IsVisible(mouseX, mouseY);
  188. return myPoint;
  189. }
  190.  
  191. public void ResetMoveFlag()
  192. {
  193. _lastMoveIndex.direct = SpliteMoveIndex.EN_DIR.NON;
  194. }
  195.  
  196. public bool SetMove(SpliteMoveIndex index)
  197. {
  198. //移动到区域外
  199. if (!index.IsIn())
  200. {
  201. _lastMoveIndex = index;
  202. return false;
  203. }
  204.  
  205. //不是同一条线
  206. if (!_lastMoveIndex.IsSameLine(index))
  207. {
  208. _lastMoveIndex = index;
  209. return false;
  210. }
  211.  
  212. //移动到新的区域
  213. MoveRect(_lastMoveIndex, index);
  214. _lastMoveIndex = index;
  215. return true;
  216. }
  217.  
  218. public bool IsInSplite()
  219. {
  220. if (_lastMoveIndex == null)
  221. return false;
  222. return _lastMoveIndex.IsIn();
  223. }
  224.  
  225. void MoveRect(SpliteMoveIndex last, SpliteMoveIndex now)
  226. {
  227. if (last.IsHorIn())
  228. {
  229. MoveRectHor(last, now);
  230. }
  231. else if (last.IsVertIn())
  232. {
  233. MoveRectVert(last, now);
  234. }
  235. }
  236.  
  237. void MoveRectHor(SpliteMoveIndex last, SpliteMoveIndex now)
  238. {
  239. int moveY = now.mouseY - last.mouseY;
  240. List<Rectangle> listSplitRectNew = new List<Rectangle>();
  241. int i = ;
  242. int find = ;
  243. foreach (Rectangle r in _listSplitRect)
  244. {
  245. Rectangle tmp = r;
  246. i++;
  247. if (find == )
  248. {
  249. listSplitRectNew.Add(tmp);
  250. continue;
  251. }
  252. if (find == )
  253. {
  254. tmp.Y += moveY;
  255. tmp.Height -= moveY;
  256. find = ;
  257. listSplitRectNew.Add(tmp);
  258. continue;
  259. }
  260.  
  261. if (i == last.rectIndex)
  262. {
  263. if (last.lineIndex == )
  264. {
  265. tmp.Y += moveY;
  266. tmp.Height -= moveY;
  267. find = ;
  268. listSplitRectNew.Add(tmp);
  269. }
  270. else if (last.lineIndex == )
  271. {
  272. tmp.Height += moveY;
  273. find = ;
  274. listSplitRectNew.Add(tmp);
  275. }
  276. }
  277. else
  278. {
  279. listSplitRectNew.Add(tmp);
  280. }
  281. }
  282.  
  283. _listSplitRect.Clear();
  284. _listSplitRect = listSplitRectNew;
  285. }
  286.  
  287. void MoveRectVert(SpliteMoveIndex last, SpliteMoveIndex now)
  288. {
  289. int moveX = now.mouseX - last.mouseX;
  290. List<Rectangle> listSplitRectNew = new List<Rectangle>();
  291. int i = ;
  292. foreach (Rectangle r in _listSplitRect)
  293. {
  294. Rectangle tmp = r;
  295. i++;
  296. if (last.lineIndex == )
  297. {
  298. tmp.X += moveX;
  299. tmp.Width -= moveX;
  300. listSplitRectNew.Add(tmp);
  301. }
  302. else if (last.lineIndex == )
  303. {
  304. tmp.Width += moveX;
  305. listSplitRectNew.Add(tmp);
  306. }
  307. }
  308.  
  309. _listSplitRect.Clear();
  310. _listSplitRect = listSplitRectNew;
  311. }
  312.  
  313. SpliteMoveIndex GetHorizontal(int x, int y, int hitSpace)
  314. {
  315. int startX = GetStartX();
  316. int width = GetSpliteWidth();
  317. if (x < startX || x > (startX + width))
  318. return SpliteMoveIndex.CreateNon(x, y);
  319.  
  320. int i = ;
  321. foreach (Rectangle rect in _listSplitRect)
  322. {
  323. i++;
  324. int y1 = rect.Y;
  325. //是否落在水平线 一定范围内
  326. if (y >= y1 - hitSpace && y <= (y1 + hitSpace))
  327. {
  328. SpliteMoveIndex moveIndex = new SpliteMoveIndex(x, y);
  329. moveIndex.direct = SpliteMoveIndex.EN_DIR.HORIZONTAL;
  330. moveIndex.rectIndex = i;
  331. moveIndex.lineIndex = ;
  332. return moveIndex;
  333. }
  334.  
  335. int y2 = rect.Y + rect.Height;
  336. if (y >= (y2 - hitSpace) && y <= (y2 + hitSpace))
  337. {
  338. SpliteMoveIndex moveIndex = new SpliteMoveIndex(x, y);
  339. moveIndex.direct = SpliteMoveIndex.EN_DIR.HORIZONTAL;
  340. moveIndex.rectIndex = i;
  341. moveIndex.lineIndex = ;
  342. return moveIndex;
  343. }
  344. }
  345.  
  346. return SpliteMoveIndex.CreateNon(x, y);
  347. }
  348.  
  349. SpliteMoveIndex GetVectical(int x, int y, int hitSpace)
  350. {
  351. int startY = GetStartY();
  352. if (y < startY || y > (startY + _heightSrc))
  353. return SpliteMoveIndex.CreateNon(x, y);
  354.  
  355. int i = ;
  356. foreach (Rectangle rect in _listSplitRect)
  357. {
  358. i++;
  359. //是否落在垂直线 一定范围内
  360. if (y >= rect.Y && y <= (rect.Y + rect.Height))
  361. {
  362. int x1 = rect.X;
  363. if (x >= (x1 - hitSpace) && x <= (x1 + hitSpace))
  364. {
  365. SpliteMoveIndex moveIndex = new SpliteMoveIndex(x, y);
  366. moveIndex.direct = SpliteMoveIndex.EN_DIR.VERTICAL;
  367. moveIndex.rectIndex = i;
  368. moveIndex.lineIndex = ;
  369. return moveIndex;
  370. }
  371.  
  372. int x2 = rect.X + rect.Width;
  373. if (x >= (x2 - hitSpace) && x <= (x2 + hitSpace))
  374. {
  375. SpliteMoveIndex moveIndex = new SpliteMoveIndex(x, y);
  376. moveIndex.direct = SpliteMoveIndex.EN_DIR.VERTICAL;
  377. moveIndex.rectIndex = i;
  378. moveIndex.lineIndex = ;
  379. return moveIndex;
  380. }
  381. }
  382. }
  383.  
  384. return SpliteMoveIndex.CreateNon(x, y);
  385. }
  386.  
  387. public SpliteMoveIndex PointHit(int x, int y, int hitSpace)
  388. {
  389. //判断是否在水平线
  390. SpliteMoveIndex hRect = GetHorizontal(x, y, hitSpace);
  391. if (hRect.IsIn())
  392. return hRect;
  393.  
  394. //判断是否在垂直线
  395. SpliteMoveIndex vRect = GetVectical(x, y, hitSpace);
  396. if (vRect.IsIn())
  397. return vRect;
  398.  
  399. return SpliteMoveIndex.CreateNon(x, y);
  400. }
  401.  
  402. public bool PointInRect(int x,int y)
  403. {
  404. int startX = GetStartX();
  405. int width = GetSpliteWidth();
  406. if (x < startX || x > (startX + width))
  407. return false;
  408.  
  409. int startY = GetStartY();
  410. int heght = GetSpliteTotalHeight();
  411. if (y < startY || y > (startY + heght))
  412. return false;
  413. return true;
  414. }
  415.  
  416. public void ClearNotUsedRect()
  417. {
  418. _listSplitRectNotUsed.Clear();
  419. }
  420.  
  421. public bool GetRectIndex(int index,ref Rectangle outRect)
  422. {
  423. int i = ;
  424. foreach (Rectangle rect in _listSplitRect)
  425. {
  426. if (i == index)
  427. {
  428. outRect = rect;
  429. return true;
  430. }
  431. i++;
  432. }
  433. return false;
  434. }
  435.  
  436. public bool IsNotUsed(int x, int y)
  437. {
  438. Rectangle rect = new Rectangle();
  439. foreach (int n in _listSplitRectNotUsed)
  440. {
  441. if (GetRectIndex(n, ref rect) && rect.Contains(x, y))
  442. {
  443. return true;
  444. }
  445. }
  446. return false;
  447. }
  448.  
  449. public bool IsRectUsed(Rectangle rect)
  450. {
  451. Rectangle rectNot = new Rectangle();
  452. foreach (int n in _listSplitRectNotUsed)
  453. {
  454. if (GetRectIndex(n, ref rectNot) && rectNot == rect)
  455. {
  456. return false;
  457. }
  458. }
  459. return true;
  460. }
  461.  
  462. public bool IsRectUsed(int index)
  463. {
  464. foreach (int n in _listSplitRectNotUsed)
  465. {
  466. if (n == index)
  467. return false;
  468. }
  469. return true;
  470. }
  471.  
  472. //区块加入切割
  473. public bool AddRectUsed(int x,int y)
  474. {
  475. int i = ;
  476. Rectangle rectNot = new Rectangle();
  477. foreach (int n in _listSplitRectNotUsed)
  478. {
  479. if (GetRectIndex(n, ref rectNot) && rectNot.Contains(x,y))
  480. {
  481. _listSplitRectNotUsed.RemoveAt(i);
  482. return true;
  483. }
  484. i++;
  485. }
  486. return false;
  487. }
  488.  
  489. //区块不加入切割
  490. public bool DelRectUsed(int x, int y)
  491. {
  492. int i = ;
  493. foreach (Rectangle rect in _listSplitRect)
  494. {
  495. if (rect.Contains(x, y))
  496. {
  497. _listSplitRectNotUsed.Add(i);
  498. return true;
  499. }
  500. i++;
  501. }
  502. return false;
  503. }
  504.  
  505. public bool AddHorLine(int x, int y)
  506. {
  507. List<Rectangle> listSplitRectNew = new List<Rectangle>();
  508. foreach (Rectangle rect in _listSplitRect)
  509. {
  510. if (y > rect.Y && y < rect.Y + rect.Height)
  511. {
  512. Rectangle r1 = new Rectangle(rect.Location, rect.Size);
  513. r1.Height = y - rect.Y;
  514. listSplitRectNew.Add(r1);
  515.  
  516. r1.Y = y ;
  517. r1.Height = (rect.Y + rect.Height - y);
  518. listSplitRectNew.Add(r1);
  519. }
  520. else
  521. {
  522. listSplitRectNew.Add(rect);
  523. }
  524. }
  525. _listSplitRect = listSplitRectNew;
  526. return true;
  527. }
  528.  
  529. //删除水平线
  530. public bool DeleteHorSplite(SpliteMoveIndex index)
  531. {
  532. List<Rectangle> listSplitRectNew = new List<Rectangle>();
  533. int i = ;
  534. bool del = false;
  535. Rectangle lastRect = new Rectangle();
  536. bool haveLast = false;
  537.  
  538. foreach (Rectangle rect in _listSplitRect)
  539. {
  540. i++;
  541. if(haveLast)
  542. {
  543. haveLast = false;
  544. lastRect.Height += rect.Height;
  545. listSplitRectNew.Add(lastRect);
  546. continue;
  547. }
  548.  
  549. if(index.rectIndex == i)
  550. {
  551. del = true;
  552. if (index.lineIndex == )
  553. {
  554. if(listSplitRectNew.Count == )
  555. {
  556. continue;
  557. }
  558. else
  559. {
  560. Rectangle r = listSplitRectNew.Last();
  561. r.Height += rect.Height;
  562. listSplitRectNew.RemoveAt(listSplitRectNew.Count-);
  563. listSplitRectNew.Add(r);
  564. }
  565. }
  566. else if (index.lineIndex == )
  567. {
  568. if(i == _listSplitRect.Count)
  569. {
  570. continue;
  571. }
  572. else
  573. {
  574. lastRect = rect;
  575. haveLast = true;
  576. }
  577. }
  578. else { Debug.Assert(false); }
  579. }
  580. else
  581. {
  582. listSplitRectNew.Add(rect);
  583. }
  584. }
  585.  
  586. _listSplitRect = listSplitRectNew;
  587. return del;
  588. }
  589.  
  590. public static int GetSplitSize(int widthSrc, int heightSrc, int startX, int startY,
  591. int widthDest, int heightDest, ref List<Rectangle> listOut)
  592. {
  593. listOut = new List<Rectangle>();
  594.  
  595. int width = Math.Min(widthSrc - startX, widthDest);
  596.  
  597. int i = ;
  598. bool stop = false;
  599. while (!stop)
  600. {
  601. Rectangle rect = new Rectangle();
  602.  
  603. rect.X = startX;
  604. rect.Y = startY + (i * heightDest);
  605. rect.Width = width;
  606. rect.Height = heightDest;
  607. if (rect.Y + rect.Height >= heightSrc)
  608. {
  609. stop = true;
  610. rect.Height = heightSrc - rect.Y;
  611. }
  612. listOut.Add(rect);
  613. i++;
  614. }
  615. return ;
  616. }
  617. }

图像快速切割

图像切割其实就是在一个内存中重新绘制,再将内存中的数据保存到文件。切割代码如下:

  1. 。。。

技术交流联系qq 13712486

一个非常好用的图片切割工具(c# winform开发)的更多相关文章

  1. 一个非常好用的图片切割工具(c# winform开发) 附源码

    本人业余时间开发了一个图片切割工具,非常好用,也很灵活! 特别对大型图片切割,更能体现出该软件的优势! 开发工具为winform,源码下载地址:http://download.csdn.net/dow ...

  2. ShoeBox一个超级好用的图片切割工具

    下载地址:http://renderhjs.net/shoebox/ ShoeBox是一个图片处理软件,体积很小. 我主要用第三个功能拆开图片.根据大图上的小图空白间隙来处理的. 导出后变成很多小图

  3. 一个web图片热点生成工具(winform开发) 附源码

    给图片加热点是web开发中经常用到的一个功能.这方面的工具也不少. 为了更好的满足自己的需求,写了一个winform程序. 可以方便的给图片加热点,更方便灵活! 源码下载 http://downloa ...

  4. 图片切割工具---产生多个div切割图片 采用for和一的二维阵列设置背景位置

    照片库 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb21vZ2c=/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  5. 网络请求以及网络请求下载图片的工具类 android开发java工具类

    package cc.jiusan.www.utils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; ...

  6. Android中将一个图片切割成多个图片

    有种场景,我们想将一个图片切割成多个图片.比如我们在开发一个拼图的游戏,就首先要对图片进行切割. 以下是封装好的两个类,可以实现图片的切割.仅供参考和学习. 一个是ImagePiece类,此类保存了一 ...

  7. Android中将一个图片切割成多个图片[转]

    有种场景,我们想将一个图片切割成多个图片.比如我们在开发一个拼图的游戏,就首先要对图片进行切割. 以下是封装好的两个类,可以实现图片的切割.仅供参考和学习. 一个是ImagePiece类,此类保存了一 ...

  8. 转: ImageMagick 命令行的图片处理工具(客户端与服务器均可用)

    http://www.imagemagick.com.cn/ 关于ImageMagick ImageMagick (TM) 是一个免费的创建.编辑.合成图片的软件.它可以读取.转换.写入多种格式的图片 ...

  9. Java操作图片的工具类

    操作图片的工具类: import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.a ...

随机推荐

  1. (最小生成树)Jungle Roads -- HDU --1301

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1301 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  2. linux的客户端安装步骤配置

    现有一个***.tar.gz的客户端软件,现在客户端安装步骤如下 说明:此软件是一个网络客户端认证软件,因为采用虚拟机中的linux主机,所以此主机的网路配置从只能使用Bridge模式,而不能使用NA ...

  3. word中添加引文操作

    word中添加引文操作 转化为pdf的时候,可以通过引文处进行ctrl + 左键点击,挑战到相应的后文中的参考引文位置. 1.在文章末尾添加如下内容,并在他的下面添加一条被引文的格式

  4. hdu 4268 贪心+set lower_bound用法

    http://acm.hdu.edu.cn/showproblem.php?pid=4268 A想用手里的牌尽量多地覆盖掉B手中的牌.. 牌有h和w 问A手中的牌最多能覆盖B多少张牌 iterator ...

  5. Android Sqlite 简单SQL语句

    --- 创建表 create table student(_id integer primary key autoincrement, name text); --- 查询全部 select _id, ...

  6. bootstrap-table 中取主键字段的问题,主键名不叫id

    问题 :取不到数据行的主键 要绑定的数据字段 RoleId rolename adddate RoleId 为主键是唯一的 bootstraptable的配置 uniqueId: "Role ...

  7. [ACM_水题] UVA 12502 Three Families [2人干3人的活后分钱,水]

      Three Families  Three families share a garden. They usually clean the garden together at the end o ...

  8. 安装docker ce版

    可参考 菜鸟教程:http://www.runoob.com/docker/centos-docker-install.html 官网教程:https://docs.docker.com/instal ...

  9. wpf expender 展开动画

    非原创,网上下载的,觉得还可以,记录一下以便以后查看学习 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2 ...

  10. 编码CODING

    摘自(复制)于海燕博客: http://www.cnblogs.com/haiyan123/p/7230533.html 1.内存和硬盘都是用来存储的. CPU:速度快 硬盘:永久保存 2.文本编辑器 ...