BitmapFilter.cs

Description du code

BitmapFilter.cs est un fichier du projet PhotoBrol.
Ce fichier est situé dans /var/www/bin/sniplets/bibliobrol/photobrol/.

Projet PhotoBrol :

Editeur d'images en CSharp.

Code source ou contenu du fichier

  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Imaging;
  4.  
  5. namespace be.gaudry.photobrol.model.filters
  6. {
  7. public class BitmapFilter
  8. {
  9. public const short EDGE_DETECT_KIRSH = 1;
  10. public const short EDGE_DETECT_PREWITT = 2;
  11. public const short EDGE_DETECT_SOBEL = 3;
  12.  
  13. public static bool Invert(Bitmap b)
  14. {
  15. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  16. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  17.  
  18. int stride = bmData.Stride;
  19. System.IntPtr Scan0 = bmData.Scan0;
  20.  
  21. unsafe
  22. {
  23. byte * p = (byte *)(void *)Scan0;
  24.  
  25. int nOffset = stride - b.Width*3;
  26. int nWidth = b.Width * 3;
  27.  
  28. for(int y=0;y<b.Height;++y)
  29. {
  30. for(int x=0; x < nWidth; ++x )
  31. {
  32. p[0] = (byte)(255-p[0]);
  33. ++p;
  34. }
  35. p += nOffset;
  36. }
  37. }
  38.  
  39. b.UnlockBits(bmData);
  40.  
  41. return true;
  42. }
  43.  
  44. public static bool GrayScale(Bitmap b)
  45. {
  46. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  47. BitmapData bmpData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  48. int remain = bmpData.Stride - bmpData.Width * 3;
  49. unsafe
  50. {
  51. byte* ptr = (byte*)bmpData.Scan0;
  52. byte t;
  53. for (int i = 0; i < bmpData.Height; i++)
  54. {
  55. for (int j = 0; j < bmpData.Width; j++)
  56. {
  57. //t = (byte)(0.333 * ptr[2] + 0.333 * ptr[1] + 0.334 * ptr[0]);
  58. t = (byte)(.299 * ptr[2] + .587 * ptr[1] + .114 * ptr[0]);
  59. ptr[2] = t;
  60. ptr[1] = t;
  61. ptr[0] = t;
  62. ptr += 3;
  63. }
  64. ptr += remain;
  65. }
  66. }
  67. b.UnlockBits(bmpData);
  68. return true;
  69. }
  70. public static bool Brightness(Bitmap b, int nBrightness)
  71. {
  72. if (nBrightness < -255 || nBrightness > 255)
  73. return false;
  74.  
  75. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  76. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  77.  
  78. int stride = bmData.Stride;
  79. System.IntPtr Scan0 = bmData.Scan0;
  80.  
  81. int nVal = 0;
  82.  
  83. unsafe
  84. {
  85. byte * p = (byte *)(void *)Scan0;
  86.  
  87. int nOffset = stride - b.Width*3;
  88. int nWidth = b.Width * 3;
  89.  
  90. for(int y=0;y<b.Height;++y)
  91. {
  92. for(int x=0; x < nWidth; ++x )
  93. {
  94. nVal = (int) (p[0] + nBrightness);
  95.  
  96. if (nVal < 0) nVal = 0;
  97. if (nVal > 255) nVal = 255;
  98.  
  99. p[0] = (byte)nVal;
  100.  
  101. ++p;
  102. }
  103. p += nOffset;
  104. }
  105. }
  106.  
  107. b.UnlockBits(bmData);
  108.  
  109. return true;
  110. }
  111.  
  112. public static bool Contrast(Bitmap b, sbyte nContrast)
  113. {
  114. if (nContrast < -100) return false;
  115. if (nContrast > 100) return false;
  116.  
  117. double pixel = 0, contrast = (100.0+nContrast)/100.0;
  118.  
  119. contrast *= contrast;
  120.  
  121. int red, green, blue;
  122.  
  123. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  124. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  125.  
  126. int stride = bmData.Stride;
  127. System.IntPtr Scan0 = bmData.Scan0;
  128.  
  129. unsafe
  130. {
  131. byte * p = (byte *)(void *)Scan0;
  132.  
  133. int nOffset = stride - b.Width*3;
  134.  
  135. for(int y=0;y<b.Height;++y)
  136. {
  137. for(int x=0; x < b.Width; ++x )
  138. {
  139. blue = p[0];
  140. green = p[1];
  141. red = p[2];
  142.  
  143. pixel = red/255.0;
  144. pixel -= 0.5;
  145. pixel *= contrast;
  146. pixel += 0.5;
  147. pixel *= 255;
  148. if (pixel < 0) pixel = 0;
  149. if (pixel > 255) pixel = 255;
  150. p[2] = (byte) pixel;
  151.  
  152. pixel = green/255.0;
  153. pixel -= 0.5;
  154. pixel *= contrast;
  155. pixel += 0.5;
  156. pixel *= 255;
  157. if (pixel < 0) pixel = 0;
  158. if (pixel > 255) pixel = 255;
  159. p[1] = (byte) pixel;
  160.  
  161. pixel = blue/255.0;
  162. pixel -= 0.5;
  163. pixel *= contrast;
  164. pixel += 0.5;
  165. pixel *= 255;
  166. if (pixel < 0) pixel = 0;
  167. if (pixel > 255) pixel = 255;
  168. p[0] = (byte) pixel;
  169.  
  170. p += 3;
  171. }
  172. p += nOffset;
  173. }
  174. }
  175.  
  176. b.UnlockBits(bmData);
  177.  
  178. return true;
  179. }
  180.  
  181. public static bool Gamma(Bitmap b, double red, double green, double blue)
  182. {
  183. if (red < .2 || red > 5) return false;
  184. if (green < .2 || green > 5) return false;
  185. if (blue < .2 || blue > 5) return false;
  186.  
  187. byte [] redGamma = new byte [256];
  188. byte [] greenGamma = new byte [256];
  189. byte [] blueGamma = new byte [256];
  190.  
  191. for (int i = 0; i< 256; ++i)
  192. {
  193. redGamma[i] = (byte)Math.Min(255, (int)(( 255.0 * Math.Pow(i/255.0, 1.0/red)) + 0.5));
  194. greenGamma[i] = (byte)Math.Min(255, (int)(( 255.0 * Math.Pow(i/255.0, 1.0/green)) + 0.5));
  195. blueGamma[i] = (byte)Math.Min(255, (int)(( 255.0 * Math.Pow(i/255.0, 1.0/blue)) + 0.5));
  196. }
  197.  
  198. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  199. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  200.  
  201. int stride = bmData.Stride;
  202. System.IntPtr Scan0 = bmData.Scan0;
  203.  
  204. unsafe
  205. {
  206. byte * p = (byte *)(void *)Scan0;
  207.  
  208. int nOffset = stride - b.Width*3;
  209.  
  210. for(int y=0;y<b.Height;++y)
  211. {
  212. for(int x=0; x < b.Width; ++x )
  213. {
  214. p[2] = redGamma[ p[2] ];
  215. p[1] = greenGamma[ p[1] ];
  216. p[0] = blueGamma[ p[0] ];
  217.  
  218. p += 3;
  219. }
  220. p += nOffset;
  221. }
  222. }
  223.  
  224. b.UnlockBits(bmData);
  225.  
  226. return true;
  227. }
  228.  
  229. public static bool ColorAvgLum(Bitmap b, int red, int green, int blue)
  230. {
  231. if (red < -255 || red > 255) return false;
  232. if (green < -255 || green > 255) return false;
  233. if (blue < -255 || blue > 255) return false;
  234.  
  235. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  236. BitmapData bmpData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  237. int remain = bmpData.Stride - bmpData.Width * 3;
  238. unsafe
  239. {
  240. byte* ptr = (byte*)bmpData.Scan0;
  241. byte temp, t;
  242. byte avg = (byte)((red + green + blue) / 3); ;
  243. for (int i = 0; i < bmpData.Height; i++)
  244. {
  245. for (int j = 0; j < bmpData.Width; j++)
  246. {
  247. //t = (byte)(0.333 * ptr[2] + 0.333 * ptr[1] + 0.334 * ptr[0]);
  248. temp = (byte)(.299 * ptr[2] + .587 * ptr[1] + .114 * ptr[0]);
  249. t = (temp - avg > 0) ? (byte)(temp - avg) : (byte)0;
  250. ptr[2] = ((byte)(((t + red) > 255) ? 255 : t + red));
  251. ptr[1] = ((byte)(((t + green) > 255) ? 255 : t + green));
  252. ptr[0] = ((byte)(((t + blue) > 255) ? 255 : t + blue));
  253. ptr += 3;
  254. }
  255. ptr += remain;
  256. }
  257. }
  258. b.UnlockBits(bmpData);
  259. return true;
  260. }
  261.  
  262.  
  263.  
  264. public static bool colorFast(Bitmap b, int red, int green, int blue)
  265. {
  266. if (red < -255 || red > 255) return false;
  267. if (green < -255 || green > 255) return false;
  268. if (blue < -255 || blue > 255) return false;
  269.  
  270. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  271. BitmapData bmpData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  272. int remain = bmpData.Stride - bmpData.Width * 3;
  273. unsafe
  274. {
  275. byte* ptr = (byte*)bmpData.Scan0;
  276. byte t;
  277. for (int i = 0; i < bmpData.Height; i++)
  278. {
  279. for (int j = 0; j < bmpData.Width; j++)
  280. {
  281. //t = (byte)(0.333 * ptr[2] + 0.333 * ptr[1] + 0.334 * ptr[0]);
  282. t = (byte)(.299 * ptr[2] + .587 * ptr[1] + .114 * ptr[0]);
  283. ptr[2] = ((byte)(((t + red) > 255) ? 255 : t + red));
  284. ptr[1] = ((byte)(((t + green) > 255) ? 255 : t + green));
  285. ptr[0] = ((byte)(((t + blue) > 255) ? 255 : t + blue));
  286. ptr += 3;
  287. }
  288. ptr += remain;
  289. }
  290. }
  291. b.UnlockBits(bmpData);
  292. return true;
  293. }
  294.  
  295. public static bool Conv3x3(Bitmap b, ConvMatrix m)
  296. {
  297. // Avoid divide by zero errors
  298. if (0 == m.Factor) return false;
  299.  
  300. Bitmap bSrc = (Bitmap)b.Clone();
  301.  
  302. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  303. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  304. BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  305.  
  306. int stride = bmData.Stride;
  307. int stride2 = stride * 2;
  308. System.IntPtr Scan0 = bmData.Scan0;
  309. System.IntPtr SrcScan0 = bmSrc.Scan0;
  310.  
  311. unsafe
  312. {
  313. byte * p = (byte *)(void *)Scan0;
  314. byte * pSrc = (byte *)(void *)SrcScan0;
  315.  
  316. int nOffset = stride - b.Width*3;
  317. int nWidth = b.Width - 2;
  318. int nHeight = b.Height - 2;
  319.  
  320. int nPixel;
  321.  
  322. for(int y=0;y < nHeight;++y)
  323. {
  324. for(int x=0; x < nWidth; ++x )
  325. {
  326. nPixel = ( ( ( (pSrc[2] * m.TopLeft) + (pSrc[5] * m.TopMid) + (pSrc[8] * m.TopRight) +
  327. (pSrc[2 + stride] * m.MidLeft) + (pSrc[5 + stride] * m.Pixel) + (pSrc[8 + stride] * m.MidRight) +
  328. (pSrc[2 + stride2] * m.BottomLeft) + (pSrc[5 + stride2] * m.BottomMid) + (pSrc[8 + stride2] * m.BottomRight)) / m.Factor) + m.Offset);
  329.  
  330. if (nPixel < 0) nPixel = 0;
  331. if (nPixel > 255) nPixel = 255;
  332.  
  333. p[5 + stride]= (byte)nPixel;
  334.  
  335. nPixel = ( ( ( (pSrc[1] * m.TopLeft) + (pSrc[4] * m.TopMid) + (pSrc[7] * m.TopRight) +
  336. (pSrc[1 + stride] * m.MidLeft) + (pSrc[4 + stride] * m.Pixel) + (pSrc[7 + stride] * m.MidRight) +
  337. (pSrc[1 + stride2] * m.BottomLeft) + (pSrc[4 + stride2] * m.BottomMid) + (pSrc[7 + stride2] * m.BottomRight)) / m.Factor) + m.Offset);
  338.  
  339. if (nPixel < 0) nPixel = 0;
  340. if (nPixel > 255) nPixel = 255;
  341.  
  342. p[4 + stride] = (byte)nPixel;
  343.  
  344. nPixel = ( ( ( (pSrc[0] * m.TopLeft) + (pSrc[3] * m.TopMid) + (pSrc[6] * m.TopRight) +
  345. (pSrc[0 + stride] * m.MidLeft) + (pSrc[3 + stride] * m.Pixel) + (pSrc[6 + stride] * m.MidRight) +
  346. (pSrc[0 + stride2] * m.BottomLeft) + (pSrc[3 + stride2] * m.BottomMid) + (pSrc[6 + stride2] * m.BottomRight)) / m.Factor) + m.Offset);
  347.  
  348. if (nPixel < 0) nPixel = 0;
  349. if (nPixel > 255) nPixel = 255;
  350.  
  351. p[3 + stride] = (byte)nPixel;
  352.  
  353. p += 3;
  354. pSrc += 3;
  355. }
  356. p += nOffset;
  357. pSrc += nOffset;
  358. }
  359. }
  360.  
  361. b.UnlockBits(bmData);
  362. bSrc.UnlockBits(bmSrc);
  363.  
  364. return true;
  365. }
  366.  
  367. public static bool Smooth(Bitmap b, int nWeight /* default to 1 */)
  368. {
  369. ConvMatrix m = new ConvMatrix();
  370. m.SetAll(1);
  371. m.Pixel = nWeight;
  372. m.Factor = nWeight + 8;
  373.  
  374. return BitmapFilter.Conv3x3(b, m);
  375. }
  376.  
  377. public static bool GaussianBlur(Bitmap b, int nWeight /* default to 4*/)
  378. {
  379. ConvMatrix m = new ConvMatrix();
  380. m.SetAll(1);
  381. m.Pixel = nWeight;
  382. m.TopMid = m.MidLeft = m.MidRight = m.BottomMid = 2;
  383. m.Factor = nWeight + 12;
  384.  
  385. return BitmapFilter.Conv3x3(b, m);
  386. }
  387. public static bool MeanRemoval(Bitmap b, int nWeight /* default to 9*/ )
  388. {
  389. ConvMatrix m = new ConvMatrix();
  390. m.SetAll(-1);
  391. m.Pixel = nWeight;
  392. m.Factor = nWeight - 8;
  393.  
  394. return BitmapFilter.Conv3x3(b, m);
  395. }
  396. public static bool Sharpen(Bitmap b, int nWeight /* default to 11*/ )
  397. {
  398. ConvMatrix m = new ConvMatrix();
  399. m.SetAll(0);
  400. m.Pixel = nWeight;
  401. m.TopMid = m.MidLeft = m.MidRight = m.BottomMid = -2;
  402. m.Factor = nWeight - 8;
  403.  
  404. return BitmapFilter.Conv3x3(b, m);
  405. }
  406. public static bool EmbossLaplacian(Bitmap b)
  407. {
  408. ConvMatrix m = new ConvMatrix();
  409. m.SetAll(-1);
  410. m.TopMid = m.MidLeft = m.MidRight = m.BottomMid = 0;
  411. m.Pixel = 4;
  412. m.Offset = 127;
  413.  
  414. return BitmapFilter.Conv3x3(b, m);
  415. }
  416. public static bool EdgeDetectQuick(Bitmap b)
  417. {
  418. ConvMatrix m = new ConvMatrix();
  419. m.TopLeft = m.TopMid = m.TopRight = -1;
  420. m.MidLeft = m.Pixel = m.MidRight = 0;
  421. m.BottomLeft = m.BottomMid = m.BottomRight = 1;
  422.  
  423. m.Offset = 127;
  424.  
  425. return BitmapFilter.Conv3x3(b, m);
  426. }
  427.  
  428. public static bool EdgeDetectConvolution(Bitmap b, short nType, byte nThreshold)
  429. {
  430. ConvMatrix m = new ConvMatrix();
  431.  
  432. // I need to make a copy of this bitmap BEFORE I alter it 80)
  433. Bitmap bTemp = (Bitmap)b.Clone();
  434.  
  435. switch (nType)
  436. {
  437. case EDGE_DETECT_SOBEL:
  438. m.SetAll(0);
  439. m.TopLeft = m.BottomLeft = 1;
  440. m.TopRight = m.BottomRight = -1;
  441. m.MidLeft = 2;
  442. m.MidRight = -2;
  443. m.Offset = 0;
  444. break;
  445. case EDGE_DETECT_PREWITT:
  446. m.SetAll(0);
  447. m.TopLeft = m.MidLeft = m.BottomLeft = -1;
  448. m.TopRight = m.MidRight = m.BottomRight = 1;
  449. m.Offset = 0;
  450. break;
  451. case EDGE_DETECT_KIRSH:
  452. m.SetAll(-3);
  453. m.Pixel = 0;
  454. m.TopLeft = m.MidLeft = m.BottomLeft = 5;
  455. m.Offset = 0;
  456. break;
  457. }
  458.  
  459. BitmapFilter.Conv3x3(b, m);
  460.  
  461. switch (nType)
  462. {
  463. case EDGE_DETECT_SOBEL:
  464. m.SetAll(0);
  465. m.TopLeft = m.TopRight = 1;
  466. m.BottomLeft = m.BottomRight = -1;
  467. m.TopMid = 2;
  468. m.BottomMid = -2;
  469. m.Offset = 0;
  470. break;
  471. case EDGE_DETECT_PREWITT:
  472. m.SetAll(0);
  473. m.BottomLeft = m.BottomMid = m.BottomRight = -1;
  474. m.TopLeft = m.TopMid = m.TopRight = 1;
  475. m.Offset = 0;
  476. break;
  477. case EDGE_DETECT_KIRSH:
  478. m.SetAll(-3);
  479. m.Pixel = 0;
  480. m.BottomLeft = m.BottomMid = m.BottomRight = 5;
  481. m.Offset = 0;
  482. break;
  483. }
  484.  
  485. BitmapFilter.Conv3x3(bTemp, m);
  486.  
  487. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  488. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  489. BitmapData bmData2 = bTemp.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  490.  
  491. int stride = bmData.Stride;
  492. System.IntPtr Scan0 = bmData.Scan0;
  493. System.IntPtr Scan02 = bmData2.Scan0;
  494.  
  495. unsafe
  496. {
  497. byte * p = (byte *)(void *)Scan0;
  498. byte * p2 = (byte *)(void *)Scan02;
  499.  
  500. int nOffset = stride - b.Width*3;
  501. int nWidth = b.Width * 3;
  502.  
  503. int nPixel = 0;
  504.  
  505. for(int y=0;y<b.Height;++y)
  506. {
  507. for(int x=0; x < nWidth; ++x )
  508. {
  509. nPixel = (int) Math.Sqrt((p[0]*p[0]) + (p2[0] * p2[0]));
  510. if (nPixel<nThreshold)nPixel = nThreshold;
  511. if (nPixel>255) nPixel = 255;
  512. p[0] = (byte) nPixel;
  513. ++p;
  514. ++p2;
  515. }
  516. p += nOffset;
  517. p2 += nOffset;
  518. }
  519. }
  520.  
  521. b.UnlockBits(bmData);
  522. bTemp.UnlockBits(bmData2);
  523.  
  524. return true;
  525. }
  526.  
  527. public static bool EdgeDetectHorizontal(Bitmap b)
  528. {
  529. Bitmap bmTemp = (Bitmap)b.Clone();
  530.  
  531. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  532. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  533. BitmapData bmData2 = bmTemp.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  534.  
  535. int stride = bmData.Stride;
  536. System.IntPtr Scan0 = bmData.Scan0;
  537. System.IntPtr Scan02 = bmData2.Scan0;
  538.  
  539. unsafe
  540. {
  541. byte * p = (byte *)(void *)Scan0;
  542. byte * p2 = (byte *)(void *)Scan02;
  543.  
  544. int nOffset = stride - b.Width*3;
  545. int nWidth = b.Width * 3;
  546.  
  547. int nPixel = 0;
  548.  
  549. p += stride;
  550. p2 += stride;
  551.  
  552. for(int y=1;y<b.Height-1;++y)
  553. {
  554. p += 9;
  555. p2 += 9;
  556.  
  557. for(int x=9; x < nWidth-9; ++x )
  558. {
  559. nPixel = ((p2 + stride - 9)[0] +
  560. (p2 + stride - 6)[0] +
  561. (p2 + stride - 3)[0] +
  562. (p2 + stride)[0] +
  563. (p2 + stride + 3)[0] +
  564. (p2 + stride + 6)[0] +
  565. (p2 + stride + 9)[0] -
  566. (p2 - stride - 9)[0] -
  567. (p2 - stride - 6)[0] -
  568. (p2 - stride - 3)[0] -
  569. (p2 - stride)[0] -
  570. (p2 - stride + 3)[0] -
  571. (p2 - stride + 6)[0] -
  572. (p2 - stride + 9)[0]);
  573.  
  574. if (nPixel < 0) nPixel = 0;
  575. if (nPixel > 255) nPixel = 255;
  576.  
  577. (p+stride)[0] = (byte) nPixel;
  578.  
  579. ++ p;
  580. ++ p2;
  581. }
  582.  
  583. p += 9 + nOffset;
  584. p2 += 9 + nOffset;
  585. }
  586. }
  587.  
  588. b.UnlockBits(bmData);
  589. bmTemp.UnlockBits(bmData2);
  590.  
  591. return true;
  592. }
  593.  
  594. public static bool EdgeDetectVertical(Bitmap b)
  595. {
  596. Bitmap bmTemp = (Bitmap)b.Clone();
  597.  
  598. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  599. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  600. BitmapData bmData2 = bmTemp.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  601.  
  602. int stride = bmData.Stride;
  603. System.IntPtr Scan0 = bmData.Scan0;
  604. System.IntPtr Scan02 = bmData2.Scan0;
  605.  
  606. unsafe
  607. {
  608. byte * p = (byte *)(void *)Scan0;
  609. byte * p2 = (byte *)(void *)Scan02;
  610.  
  611. int nOffset = stride - b.Width*3;
  612. int nWidth = b.Width * 3;
  613.  
  614. int nPixel = 0;
  615.  
  616. int nStride2 = stride *2;
  617. int nStride3 = stride * 3;
  618.  
  619. p += nStride3;
  620. p2 += nStride3;
  621.  
  622. for(int y=3;y<b.Height-3;++y)
  623. {
  624. p += 3;
  625. p2 += 3;
  626.  
  627. for(int x=3; x < nWidth-3; ++x )
  628. {
  629. nPixel = ((p2 + nStride3 + 3)[0] +
  630. (p2 + nStride2 + 3)[0] +
  631. (p2 + stride + 3)[0] +
  632. (p2 + 3)[0] +
  633. (p2 - stride + 3)[0] +
  634. (p2 - nStride2 + 3)[0] +
  635. (p2 - nStride3 + 3)[0] -
  636. (p2 + nStride3 - 3)[0] -
  637. (p2 + nStride2 - 3)[0] -
  638. (p2 + stride - 3)[0] -
  639. (p2 - 3)[0] -
  640. (p2 - stride - 3)[0] -
  641. (p2 - nStride2 - 3)[0] -
  642. (p2 - nStride3 - 3)[0]);
  643.  
  644. if (nPixel < 0) nPixel = 0;
  645. if (nPixel > 255) nPixel = 255;
  646.  
  647. p[0] = (byte) nPixel;
  648.  
  649. ++ p;
  650. ++ p2;
  651. }
  652.  
  653. p += 3 + nOffset;
  654. p2 += 3 + nOffset;
  655. }
  656. }
  657.  
  658. b.UnlockBits(bmData);
  659. bmTemp.UnlockBits(bmData2);
  660.  
  661. return true;
  662. }
  663.  
  664. public static bool EdgeDetectHomogenity(Bitmap b, byte nThreshold)
  665. {
  666. // This one works by working out the greatest difference between a pixel and it's eight neighbours.
  667. // The threshold allows softer edges to be forced down to black, use 0 to negate it's effect.
  668. Bitmap b2 = (Bitmap) b.Clone();
  669.  
  670. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  671. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  672. BitmapData bmData2 = b2.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  673.  
  674. int stride = bmData.Stride;
  675. System.IntPtr Scan0 = bmData.Scan0;
  676. System.IntPtr Scan02 = bmData2.Scan0;
  677.  
  678. unsafe
  679. {
  680. byte * p = (byte *)(void *)Scan0;
  681. byte * p2 = (byte *)(void *)Scan02;
  682.  
  683. int nOffset = stride - b.Width*3;
  684. int nWidth = b.Width * 3;
  685.  
  686. int nPixel = 0, nPixelMax = 0;
  687.  
  688. p += stride;
  689. p2 += stride;
  690.  
  691. for(int y=1;y<b.Height-1;++y)
  692. {
  693. p += 3;
  694. p2 += 3;
  695.  
  696. for(int x=3; x < nWidth-3; ++x )
  697. {
  698. nPixelMax = Math.Abs(p2[0] - (p2+stride-3)[0]);
  699. nPixel = Math.Abs(p2[0] - (p2 + stride)[0]);
  700. if (nPixel>nPixelMax) nPixelMax = nPixel;
  701.  
  702. nPixel = Math.Abs(p2[0] - (p2 + stride + 3)[0]);
  703. if (nPixel>nPixelMax) nPixelMax = nPixel;
  704.  
  705. nPixel = Math.Abs(p2[0] - (p2 - stride)[0]);
  706. if (nPixel>nPixelMax) nPixelMax = nPixel;
  707.  
  708. nPixel = Math.Abs(p2[0] - (p2 + stride)[0]);
  709. if (nPixel>nPixelMax) nPixelMax = nPixel;
  710.  
  711. nPixel = Math.Abs(p2[0] - (p2 - stride - 3)[0]);
  712. if (nPixel>nPixelMax) nPixelMax = nPixel;
  713.  
  714. nPixel = Math.Abs(p2[0] - (p2 - stride)[0]);
  715. if (nPixel>nPixelMax) nPixelMax = nPixel;
  716.  
  717. nPixel = Math.Abs(p2[0] - (p2 - stride + 3)[0]);
  718. if (nPixel>nPixelMax) nPixelMax = nPixel;
  719.  
  720. if (nPixelMax < nThreshold) nPixelMax = 0;
  721.  
  722. p[0] = (byte) nPixelMax;
  723.  
  724. ++ p;
  725. ++ p2;
  726. }
  727.  
  728. p += 3 + nOffset;
  729. p2 += 3 + nOffset;
  730. }
  731. }
  732.  
  733. b.UnlockBits(bmData);
  734. b2.UnlockBits(bmData2);
  735.  
  736. return true;
  737.  
  738. }
  739. public static bool EdgeDetectDifference(Bitmap b, byte nThreshold)
  740. {
  741. // This one works by working out the greatest difference between a pixel and it's eight neighbours.
  742. // The threshold allows softer edges to be forced down to black, use 0 to negate it's effect.
  743. Bitmap b2 = (Bitmap) b.Clone();
  744.  
  745. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  746. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  747. BitmapData bmData2 = b2.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  748.  
  749. int stride = bmData.Stride;
  750. System.IntPtr Scan0 = bmData.Scan0;
  751. System.IntPtr Scan02 = bmData2.Scan0;
  752.  
  753. unsafe
  754. {
  755. byte * p = (byte *)(void *)Scan0;
  756. byte * p2 = (byte *)(void *)Scan02;
  757.  
  758. int nOffset = stride - b.Width*3;
  759. int nWidth = b.Width * 3;
  760.  
  761. int nPixel = 0, nPixelMax = 0;
  762.  
  763. p += stride;
  764. p2 += stride;
  765.  
  766. for(int y=1;y<b.Height-1;++y)
  767. {
  768. p += 3;
  769. p2 += 3;
  770.  
  771. for(int x=3; x < nWidth-3; ++x )
  772. {
  773. nPixelMax = Math.Abs((p2 - stride + 3)[0] - (p2+stride-3)[0]);
  774. nPixel = Math.Abs((p2 + stride + 3)[0] - (p2 - stride - 3)[0]);
  775. if (nPixel>nPixelMax) nPixelMax = nPixel;
  776.  
  777. nPixel = Math.Abs((p2 - stride)[0] - (p2 + stride)[0]);
  778. if (nPixel>nPixelMax) nPixelMax = nPixel;
  779.  
  780. nPixel = Math.Abs((p2+3)[0] - (p2 - 3)[0]);
  781. if (nPixel>nPixelMax) nPixelMax = nPixel;
  782.  
  783. if (nPixelMax < nThreshold) nPixelMax = 0;
  784.  
  785. p[0] = (byte) nPixelMax;
  786.  
  787. ++ p;
  788. ++ p2;
  789. }
  790.  
  791. p += 3 + nOffset;
  792. p2 += 3 + nOffset;
  793. }
  794. }
  795.  
  796. b.UnlockBits(bmData);
  797. b2.UnlockBits(bmData2);
  798.  
  799. return true;
  800.  
  801. }
  802.  
  803. public static bool EdgeEnhance(Bitmap b, byte nThreshold)
  804. {
  805. // This one works by working out the greatest difference between a nPixel and it's eight neighbours.
  806. // The threshold allows softer edges to be forced down to black, use 0 to negate it's effect.
  807. Bitmap b2 = (Bitmap) b.Clone();
  808.  
  809. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  810. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  811. BitmapData bmData2 = b2.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  812.  
  813. int stride = bmData.Stride;
  814. System.IntPtr Scan0 = bmData.Scan0;
  815. System.IntPtr Scan02 = bmData2.Scan0;
  816.  
  817. unsafe
  818. {
  819. byte * p = (byte *)(void *)Scan0;
  820. byte * p2 = (byte *)(void *)Scan02;
  821.  
  822. int nOffset = stride - b.Width*3;
  823. int nWidth = b.Width * 3;
  824.  
  825. int nPixel = 0, nPixelMax = 0;
  826.  
  827. p += stride;
  828. p2 += stride;
  829.  
  830. for (int y = 1; y < b.Height-1; ++y)
  831. {
  832. p += 3;
  833. p2 += 3;
  834.  
  835. for (int x = 3; x < nWidth-3; ++x)
  836. {
  837. nPixelMax = Math.Abs((p2 - stride + 3)[0] - (p2 + stride - 3)[0]);
  838.  
  839. nPixel = Math.Abs((p2 + stride + 3)[0] - (p2 - stride - 3)[0]);
  840.  
  841. if (nPixel > nPixelMax) nPixelMax = nPixel;
  842.  
  843. nPixel = Math.Abs((p2 - stride)[0] - (p2 + stride)[0]);
  844.  
  845. if (nPixel > nPixelMax) nPixelMax = nPixel;
  846.  
  847. nPixel = Math.Abs((p2 + 3)[0] - (p2 - 3)[0]);
  848.  
  849. if (nPixel > nPixelMax) nPixelMax = nPixel;
  850.  
  851. if (nPixelMax > nThreshold && nPixelMax > p[0])
  852. p[0] = (byte) Math.Max(p[0], nPixelMax);
  853.  
  854. ++ p;
  855. ++ p2;
  856. }
  857.  
  858. p += nOffset + 3;
  859. p2 += nOffset + 3;
  860. }
  861. }
  862.  
  863. b.UnlockBits(bmData);
  864. b2.UnlockBits(bmData2);
  865.  
  866. return true;
  867. }
  868. public static Bitmap Resize(Bitmap b, int nWidth, int nHeight, bool bBilinear)
  869. {
  870. Bitmap bTemp = (Bitmap)b.Clone();
  871. b = new Bitmap(nWidth, nHeight, bTemp.PixelFormat);
  872.  
  873. double nXFactor = (double)bTemp.Width/(double)nWidth;
  874. double nYFactor = (double)bTemp.Height/(double)nHeight;
  875.  
  876. if (bBilinear)
  877. {
  878. double fraction_x, fraction_y, one_minus_x, one_minus_y;
  879. int ceil_x, ceil_y, floor_x, floor_y;
  880. Color c1 = new Color();
  881. Color c2 = new Color();
  882. Color c3 = new Color();
  883. Color c4 = new Color();
  884. byte red, green, blue;
  885.  
  886. byte b1, b2;
  887.  
  888. for (int x = 0; x < b.Width; ++x)
  889. for (int y = 0; y < b.Height; ++y)
  890. {
  891. // Setup
  892.  
  893. floor_x = (int)Math.Floor(x * nXFactor);
  894. floor_y = (int)Math.Floor(y * nYFactor);
  895. ceil_x = floor_x + 1;
  896. if (ceil_x >= bTemp.Width) ceil_x = floor_x;
  897. ceil_y = floor_y + 1;
  898. if (ceil_y >= bTemp.Height) ceil_y = floor_y;
  899. fraction_x = x * nXFactor - floor_x;
  900. fraction_y = y * nYFactor - floor_y;
  901. one_minus_x = 1.0 - fraction_x;
  902. one_minus_y = 1.0 - fraction_y;
  903.  
  904. c1 = bTemp.GetPixel(floor_x, floor_y);
  905. c2 = bTemp.GetPixel(ceil_x, floor_y);
  906. c3 = bTemp.GetPixel(floor_x, ceil_y);
  907. c4 = bTemp.GetPixel(ceil_x, ceil_y);
  908.  
  909. // Blue
  910. b1 = (byte)(one_minus_x * c1.B + fraction_x * c2.B);
  911.  
  912. b2 = (byte)(one_minus_x * c3.B + fraction_x * c4.B);
  913.  
  914. blue = (byte)(one_minus_y * (double)(b1) + fraction_y * (double)(b2));
  915.  
  916. // Green
  917. b1 = (byte)(one_minus_x * c1.G + fraction_x * c2.G);
  918.  
  919. b2 = (byte)(one_minus_x * c3.G + fraction_x * c4.G);
  920.  
  921. green = (byte)(one_minus_y * (double)(b1) + fraction_y * (double)(b2));
  922.  
  923. // Red
  924. b1 = (byte)(one_minus_x * c1.R + fraction_x * c2.R);
  925.  
  926. b2 = (byte)(one_minus_x * c3.R + fraction_x * c4.R);
  927.  
  928. red = (byte)(one_minus_y * (double)(b1) + fraction_y * (double)(b2));
  929.  
  930. b.SetPixel(x,y, System.Drawing.Color.FromArgb(255, red, green, blue));
  931. }
  932. }
  933. else
  934. {
  935. for (int x = 0; x < b.Width; ++x)
  936. for (int y = 0; y < b.Height; ++y)
  937. b.SetPixel(x, y, bTemp.GetPixel((int)(Math.Floor(x * nXFactor)),(int)(Math.Floor(y * nYFactor))));
  938. }
  939.  
  940. return b;
  941. }
  942.  
  943. public static bool OffsetFilterAbs(Bitmap b, Point[,] offset )
  944. {
  945. Bitmap bSrc = (Bitmap)b.Clone();
  946.  
  947. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  948. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  949. BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  950.  
  951. int scanline = bmData.Stride;
  952.  
  953. System.IntPtr Scan0 = bmData.Scan0;
  954. System.IntPtr SrcScan0 = bmSrc.Scan0;
  955.  
  956. unsafe
  957. {
  958. byte * p = (byte *)(void *)Scan0;
  959. byte * pSrc = (byte *)(void *)SrcScan0;
  960.  
  961. int nOffset = bmData.Stride - b.Width*3;
  962. int nWidth = b.Width;
  963. int nHeight = b.Height;
  964.  
  965. int xOffset, yOffset;
  966.  
  967. for(int y=0;y < nHeight;++y)
  968. {
  969. for(int x=0; x < nWidth; ++x )
  970. {
  971. xOffset = offset[x,y].X;
  972. yOffset = offset[x,y].Y;
  973.  
  974. if (yOffset >= 0 && yOffset < nHeight && xOffset >= 0 && xOffset < nWidth)
  975. {
  976. p[0] = pSrc[(yOffset * scanline) + (xOffset * 3)];
  977. p[1] = pSrc[(yOffset * scanline) + (xOffset * 3) + 1];
  978. p[2] = pSrc[(yOffset * scanline) + (xOffset * 3) + 2];
  979. }
  980.  
  981. p += 3;
  982. }
  983. p += nOffset;
  984. }
  985. }
  986.  
  987. b.UnlockBits(bmData);
  988. bSrc.UnlockBits(bmSrc);
  989.  
  990. return true;
  991. }
  992.  
  993. public static bool OffsetFilter(Bitmap b, Point[,] offset )
  994. {
  995. Bitmap bSrc = (Bitmap)b.Clone();
  996.  
  997. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  998. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  999. BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  1000.  
  1001. int scanline = bmData.Stride;
  1002.  
  1003. System.IntPtr Scan0 = bmData.Scan0;
  1004. System.IntPtr SrcScan0 = bmSrc.Scan0;
  1005.  
  1006. unsafe
  1007. {
  1008. byte * p = (byte *)(void *)Scan0;
  1009. byte * pSrc = (byte *)(void *)SrcScan0;
  1010.  
  1011. int nOffset = bmData.Stride - b.Width*3;
  1012. int nWidth = b.Width;
  1013. int nHeight = b.Height;
  1014.  
  1015. int xOffset, yOffset;
  1016.  
  1017. for(int y=0;y < nHeight;++y)
  1018. {
  1019. for(int x=0; x < nWidth; ++x )
  1020. {
  1021. xOffset = offset[x,y].X;
  1022. yOffset = offset[x,y].Y;
  1023.  
  1024. if (y+yOffset >= 0 && y+yOffset < nHeight && x+xOffset >= 0 && x+xOffset < nWidth)
  1025. {
  1026. p[0] = pSrc[((y+yOffset) * scanline) + ((x+xOffset) * 3)];
  1027. p[1] = pSrc[((y+yOffset) * scanline) + ((x+xOffset) * 3) + 1];
  1028. p[2] = pSrc[((y+yOffset) * scanline) + ((x+xOffset) * 3) + 2];
  1029. }
  1030.  
  1031. p += 3;
  1032. }
  1033. p += nOffset;
  1034. }
  1035. }
  1036.  
  1037. b.UnlockBits(bmData);
  1038. bSrc.UnlockBits(bmSrc);
  1039.  
  1040. return true;
  1041. }
  1042.  
  1043. public static bool OffsetFilterAntiAlias(Bitmap b, FloatPoint[,] fp)
  1044. {
  1045. Bitmap bSrc = (Bitmap)b.Clone();
  1046.  
  1047. // !! Don't forget GDI+ uses BGR format and nor RGB !!!
  1048. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  1049. BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  1050.  
  1051. int scanline = bmData.Stride;
  1052.  
  1053. System.IntPtr Scan0 = bmData.Scan0;
  1054. System.IntPtr SrcScan0 = bmSrc.Scan0;
  1055.  
  1056. unsafe
  1057. {
  1058. byte * p = (byte *)(void *)Scan0;
  1059. byte * pSrc = (byte *)(void *)SrcScan0;
  1060.  
  1061. int nOffset = bmData.Stride - b.Width*3;
  1062. int nWidth = b.Width;
  1063. int nHeight = b.Height;
  1064.  
  1065. double xOffset, yOffset;
  1066.  
  1067. double fraction_x, fraction_y, one_minus_x, one_minus_y;
  1068. int ceil_x, ceil_y, floor_x, floor_y;
  1069. Byte p1, p2;
  1070.  
  1071. for(int y=0;y < nHeight;++y)
  1072. {
  1073. for(int x=0; x < nWidth; ++x )
  1074. {
  1075. xOffset = fp[x,y].X;
  1076. yOffset = fp[x,y].Y;
  1077.  
  1078. // Setup
  1079.  
  1080. floor_x = (int)Math.Floor(xOffset);
  1081. floor_y = (int)Math.Floor(yOffset);
  1082. ceil_x = floor_x + 1;
  1083. ceil_y = floor_y + 1;
  1084. fraction_x = xOffset - floor_x;
  1085. fraction_y = yOffset - floor_y;
  1086. one_minus_x = 1.0 - fraction_x;
  1087. one_minus_y = 1.0 - fraction_y;
  1088.  
  1089. if (floor_y >= 0 && ceil_y < nHeight && floor_x >= 0 && ceil_x < nWidth)
  1090. {
  1091. // Blue
  1092.  
  1093. p1 = (Byte)(one_minus_x * (double)(pSrc[floor_y * scanline + floor_x * 3]) +
  1094. fraction_x * (double)(pSrc[floor_y * scanline + ceil_x * 3]));
  1095.  
  1096. p2 = (Byte)(one_minus_x * (double)(pSrc[ceil_y * scanline + floor_x * 3]) +
  1097. fraction_x * (double)(pSrc[ceil_y * scanline + 3 * ceil_x]));
  1098.  
  1099. p[x * 3 + y*scanline] = (Byte)(one_minus_y * (double)(p1) + fraction_y * (double)(p2));
  1100.  
  1101. // Green
  1102.  
  1103. p1 = (Byte)(one_minus_x * (double)(pSrc[floor_y * scanline + floor_x * 3 + 1]) +
  1104. fraction_x * (double)(pSrc[floor_y * scanline + ceil_x * 3 + 1]));
  1105.  
  1106. p2 = (Byte)(one_minus_x * (double)(pSrc[ceil_y * scanline + floor_x * 3 + 1]) +
  1107. fraction_x * (double)(pSrc[ceil_y * scanline + 3 * ceil_x + 1]));
  1108.  
  1109. p[x * 3 + y*scanline + 1] = (Byte)(one_minus_y * (double)(p1) + fraction_y * (double)(p2));
  1110.  
  1111. // Red
  1112.  
  1113. p1 = (Byte)(one_minus_x * (double)(pSrc[floor_y * scanline + floor_x * 3 + 2]) +
  1114. fraction_x * (double)(pSrc[floor_y * scanline + ceil_x * 3 + 2]));
  1115.  
  1116. p2 = (Byte)(one_minus_x * (double)(pSrc[ceil_y * scanline + floor_x * 3 + 2]) +
  1117. fraction_x * (double)(pSrc[ceil_y * scanline + 3 * ceil_x + 2]));
  1118.  
  1119. p[x * 3 + y*scanline + 2] = (Byte)(one_minus_y * (double)(p1) + fraction_y * (double)(p2));
  1120. }
  1121. }
  1122. }
  1123. }
  1124.  
  1125. b.UnlockBits(bmData);
  1126. bSrc.UnlockBits(bmSrc);
  1127.  
  1128. return true;
  1129. }
  1130.  
  1131. public static bool Flip(Bitmap b, bool bHorz, bool bVert)
  1132. {
  1133. Point [,] ptFlip = new Point[b.Width,b.Height];
  1134.  
  1135. int nWidth = b.Width;
  1136. int nHeight = b.Height;
  1137.  
  1138. for (int x = 0; x < nWidth; ++x)
  1139. for (int y = 0; y < nHeight; ++y)
  1140. {
  1141. ptFlip[x, y].X = (bHorz) ? nWidth - (x+1) : x;
  1142. ptFlip[x,y].Y = (bVert) ? nHeight - (y + 1) : y;
  1143. }
  1144.  
  1145. OffsetFilterAbs(b, ptFlip);
  1146.  
  1147. return true;
  1148. }
  1149.  
  1150. public static bool RandomJitter(Bitmap b, short nDegree)
  1151. {
  1152. Point [,] ptRandJitter = new Point[b.Width,b.Height];
  1153.  
  1154. int nWidth = b.Width;
  1155. int nHeight = b.Height;
  1156.  
  1157. int newX, newY;
  1158.  
  1159. short nHalf = (short)Math.Floor((double)nDegree/2);
  1160. Random rnd = new Random();
  1161.  
  1162. for (int x = 0; x < nWidth; ++x)
  1163. for (int y = 0; y < nHeight; ++y)
  1164. {
  1165. newX = rnd.Next(nDegree) - nHalf;
  1166.  
  1167. if (x + newX > 0 && x + newX < nWidth)
  1168. ptRandJitter[x, y].X = newX;
  1169. else
  1170. ptRandJitter[x, y].X = 0;
  1171.  
  1172. newY = rnd.Next(nDegree) - nHalf;
  1173.  
  1174. if (y + newY > 0 && y + newY < nWidth)
  1175. ptRandJitter[x, y].Y = newY;
  1176. else
  1177. ptRandJitter[x, y].Y = 0;
  1178. }
  1179.  
  1180. OffsetFilter(b, ptRandJitter);
  1181.  
  1182. return true;
  1183. }
  1184. public static bool Swirl(Bitmap b, double fDegree, bool bSmoothing /* default fDegree to .05 */)
  1185. {
  1186. int nWidth = b.Width;
  1187. int nHeight = b.Height;
  1188.  
  1189. FloatPoint [,] fp = new FloatPoint[nWidth, nHeight];
  1190. Point [,] pt = new Point[nWidth, nHeight];
  1191.  
  1192. Point mid = new Point();
  1193. mid.X = nWidth/2;
  1194. mid.Y = nHeight/2;
  1195.  
  1196. double theta, radius;
  1197. double newX, newY;
  1198.  
  1199. for (int x = 0; x < nWidth; ++x)
  1200. for (int y = 0; y < nHeight; ++y)
  1201. {
  1202. int trueX = x - mid.X;
  1203. int trueY = y - mid.Y;
  1204. theta = Math.Atan2((trueY),(trueX));
  1205.  
  1206. radius = Math.Sqrt(trueX*trueX + trueY*trueY);
  1207.  
  1208. newX = mid.X + (radius * Math.Cos(theta + fDegree * radius));
  1209. if (newX > 0 && newX < nWidth)
  1210. {
  1211. fp[x, y].X = newX;
  1212. pt[x, y].X = (int)newX;
  1213. }
  1214. else
  1215. fp[x, y].X = pt[x, y].X = x;
  1216.  
  1217. newY = mid.Y + (radius * Math.Sin(theta + fDegree * radius));
  1218. if (newY > 0 && newY < nHeight)
  1219. {
  1220. fp[x, y].Y = newY;
  1221. pt[x, y].Y = (int)newY;
  1222. }
  1223. else
  1224. fp[x, y].Y = pt[x, y].Y = y;
  1225. }
  1226.  
  1227. if(bSmoothing)
  1228. OffsetFilterAntiAlias(b, fp);
  1229. else
  1230. OffsetFilterAbs(b, pt);
  1231.  
  1232. return true;
  1233. }
  1234.  
  1235. public static bool Sphere(Bitmap b, bool bSmoothing, int displacement, int expand)
  1236. {
  1237. int nWidth = b.Width;
  1238. int nHeight = b.Height;
  1239.  
  1240. FloatPoint [,] fp = new FloatPoint[nWidth, nHeight];
  1241. Point [,] pt = new Point[nWidth, nHeight];
  1242.  
  1243. Point mid = new Point();
  1244. mid.X = nWidth / 2;
  1245. mid.Y = nHeight / 2;
  1246.  
  1247. double theta, radius;
  1248. double newX, newY;
  1249.  
  1250. for (int x = 0; x < nWidth; ++x)
  1251. for (int y = 0; y < nHeight; ++y)
  1252. {
  1253. int trueX = x - mid.X;
  1254. int trueY = y - mid.Y;
  1255. theta = Math.Atan2((trueY), (trueX));
  1256.  
  1257. radius = Math.Sqrt(trueX*trueX + trueY*trueY);
  1258.  
  1259. double newRadius = radius * radius/(Math.Max(mid.X, mid.Y));
  1260.  
  1261. newX = mid.X + (newRadius * Math.Cos(theta)) + displacement;
  1262.  
  1263. if (newX > 0 && newX < nWidth)
  1264. {
  1265. fp[x, y].X = newX;
  1266. pt[x, y].X = (int) newX;
  1267. }
  1268. else
  1269. {
  1270. fp[x, y].X = fp[x,y].Y = 0.0;
  1271. pt[x, y].X = pt[x,y].Y = 0;
  1272. }
  1273.  
  1274. newY = mid.Y + (newRadius * Math.Sin(theta)) + expand;
  1275.  
  1276. if (newY > 0 && newY < nHeight && newX > 0 && newX < nWidth)
  1277. {
  1278. fp[x, y].Y = newY;
  1279. pt[x, y].Y = (int) newY;
  1280. }
  1281. else
  1282. {
  1283. fp[x, y].X = fp[x,y].Y = 0.0;
  1284. pt[x, y].X = pt[x,y].Y = 0;
  1285. }
  1286. }
  1287.  
  1288. if(bSmoothing)
  1289. OffsetFilterAbs(b, pt);
  1290. else
  1291. OffsetFilterAntiAlias(b, fp);
  1292.  
  1293. return true;
  1294. }
  1295.  
  1296. public static bool TimeWarp(Bitmap b, Byte factor, bool bSmoothing)
  1297. {
  1298. int nWidth = b.Width;
  1299. int nHeight = b.Height;
  1300.  
  1301. FloatPoint [,] fp = new FloatPoint[nWidth, nHeight];
  1302. Point [,] pt = new Point[nWidth, nHeight];
  1303.  
  1304. Point mid = new Point();
  1305. mid.X = nWidth/2;
  1306. mid.Y = nHeight/2;
  1307.  
  1308. double theta, radius;
  1309. double newX, newY;
  1310.  
  1311. for (int x = 0; x < nWidth; ++x)
  1312. for (int y = 0; y < nHeight; ++y)
  1313. {
  1314. int trueX = x - mid.X;
  1315. int trueY = y - mid.Y;
  1316. theta = Math.Atan2((trueY),(trueX));
  1317.  
  1318. radius = Math.Sqrt(trueX*trueX + trueY*trueY);
  1319.  
  1320. double newRadius = Math.Sqrt(radius) * factor;
  1321.  
  1322. newX = mid.X + (newRadius * Math.Cos(theta));
  1323. if (newX > 0 && newX < nWidth)
  1324. {
  1325. fp[x, y].X = newX;
  1326. pt[x, y].X = (int) newX;
  1327. }
  1328. else
  1329. {
  1330. fp[x, y].X = 0.0;
  1331. pt[x, y].X = 0;
  1332. }
  1333.  
  1334. newY = mid.Y + (newRadius * Math.Sin(theta));
  1335. if (newY > 0 && newY < nHeight)
  1336. {
  1337. fp[x, y].Y = newY;
  1338. pt[x, y].Y = (int) newY;
  1339. }
  1340. else
  1341. {
  1342. fp[x, y].Y = 0.0;
  1343. pt[x, y].Y = 0;
  1344. }
  1345. }
  1346.  
  1347. if(bSmoothing)
  1348. OffsetFilterAbs(b, pt);
  1349. else
  1350. OffsetFilterAntiAlias(b, fp);
  1351.  
  1352. return true;
  1353. }
  1354.  
  1355. public static bool Moire(Bitmap b, double fDegree)
  1356. {
  1357. int nWidth = b.Width;
  1358. int nHeight = b.Height;
  1359.  
  1360. Point [,] pt = new Point[nWidth, nHeight];
  1361.  
  1362. Point mid = new Point();
  1363. mid.X = nWidth/2;
  1364. mid.Y = nHeight/2;
  1365.  
  1366. double theta, radius;
  1367. int newX, newY;
  1368.  
  1369. for (int x = 0; x < nWidth; ++x)
  1370. for (int y = 0; y < nHeight; ++y)
  1371. {
  1372. int trueX = x - mid.X;
  1373. int trueY = y - mid.Y;
  1374. theta = Math.Atan2((trueX),(trueY));
  1375.  
  1376. radius = Math.Sqrt(trueX*trueX + trueY*trueY);
  1377.  
  1378. newX = (int)(radius * Math.Sin(theta + fDegree * radius));
  1379. if (newX > 0 && newX < nWidth)
  1380. {
  1381. pt[x, y].X = (int) newX;
  1382. }
  1383. else
  1384. {
  1385. pt[x, y].X = 0;
  1386. }
  1387.  
  1388. newY = (int)(radius * Math.Sin(theta + fDegree * radius));
  1389. if (newY > 0 && newY < nHeight)
  1390. {
  1391. pt[x, y].Y = (int) newY;
  1392. }
  1393. else
  1394. {
  1395. pt[x, y].Y = 0;
  1396. }
  1397. }
  1398.  
  1399. OffsetFilterAbs(b, pt);
  1400.  
  1401. return true;
  1402. }
  1403.  
  1404. public static bool Water(Bitmap b, short nWave, bool bSmoothing)
  1405. {
  1406. int nWidth = b.Width;
  1407. int nHeight = b.Height;
  1408.  
  1409. FloatPoint [,] fp = new FloatPoint[nWidth, nHeight];
  1410. Point [,] pt = new Point[nWidth, nHeight];
  1411.  
  1412. Point mid = new Point();
  1413. mid.X = nWidth/2;
  1414. mid.Y = nHeight/2;
  1415.  
  1416. double newX, newY;
  1417. double xo, yo;
  1418.  
  1419. for (int x = 0; x < nWidth; ++x)
  1420. for (int y = 0; y < nHeight; ++y)
  1421. {
  1422. xo = ((double)nWave * Math.Sin(2.0 * 3.1415 * (float)y / 128.0));
  1423. yo = ((double)nWave * Math.Cos(2.0 * 3.1415 * (float)x / 128.0));
  1424.  
  1425. newX = (x + xo);
  1426. newY = (y + yo);
  1427.  
  1428. if (newX > 0 && newX < nWidth)
  1429. {
  1430. fp[x, y].X = newX;
  1431. pt[x, y].X = (int) newX;
  1432. }
  1433. else
  1434. {
  1435. fp[x, y].X = 0.0;
  1436. pt[x, y].X = 0;
  1437. }
  1438.  
  1439.  
  1440. if (newY > 0 && newY < nHeight)
  1441. {
  1442. fp[x, y].Y = newY;
  1443. pt[x, y].Y = (int) newY;
  1444. }
  1445. else
  1446. {
  1447. fp[x, y].Y = 0.0;
  1448. pt[x, y].Y = 0;
  1449. }
  1450. }
  1451.  
  1452. if(bSmoothing)
  1453. OffsetFilterAbs(b, pt);
  1454. else
  1455. OffsetFilterAntiAlias(b, fp);
  1456.  
  1457. return true;
  1458. }
  1459.  
  1460. public static bool Pixelate(Bitmap b, short pixel, bool bGrid)
  1461. {
  1462. int nWidth = b.Width;
  1463. int nHeight = b.Height;
  1464.  
  1465. Point [,] pt = new Point[nWidth, nHeight];
  1466.  
  1467. int newX, newY;
  1468.  
  1469. for (int x = 0; x < nWidth; ++x)
  1470. for (int y = 0; y < nHeight; ++y)
  1471. {
  1472. newX = pixel - x%pixel;
  1473.  
  1474. if (bGrid && newX == pixel)
  1475. pt[x, y].X = -x;
  1476. else if (x + newX > 0 && x +newX < nWidth)
  1477. pt[x, y].X = newX;
  1478. else
  1479. pt[x, y].X = 0;
  1480.  
  1481. newY = pixel - y%pixel;
  1482.  
  1483. if (bGrid && newY == pixel)
  1484. pt[x, y].Y = -y;
  1485. else if (y + newY > 0 && y + newY < nHeight)
  1486. pt[x, y].Y = newY;
  1487. else
  1488. pt[x, y].Y = 0;
  1489. }
  1490.  
  1491. OffsetFilter(b, pt);
  1492.  
  1493. return true;
  1494. }
  1495.  
  1496. public static bool sepia(Bitmap b, int red, int green, int blue)
  1497. {
  1498. BitmapData bmpData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
  1499. int remain = bmpData.Stride - bmpData.Width * 3;
  1500. unsafe
  1501. {
  1502. byte* ptr = (byte*)bmpData.Scan0;
  1503. for (int i = 0; i < bmpData.Height; i++)
  1504. {
  1505. for (int j = 0; j < bmpData.Width; j++)
  1506. {
  1507. byte t = (byte)(0.299 * ptr[2] + 0.587 * ptr[1] + 0.114 * ptr[0]);
  1508. ptr[2] = ((byte)((t > (206+red)) ? 255 : t + 49+red));
  1509. ptr[1] = ((byte)((t < (14+green)) ? 0 : t - (14+green)));
  1510. ptr[0] = ((byte)((t < (56+blue)) ? 0 : t - (56+blue)));
  1511. ptr += 3;
  1512. } /*
  1513.   for (int j = 0; j < bmpData.Width; j++)
  1514.   {
  1515.   byte t = (byte)(0.299 * ptr[2] + 0.587 * ptr[1] + 0.114 * ptr[0]);
  1516.   ptr[2] = ((byte)((t > red) ? 255 : t + red));
  1517.   ptr[1] = ((byte)((t > green) ? 255 : t + green));
  1518.   ptr[0] = ((byte)((t > blue) ? 255 : t + blue));
  1519.   ptr += 3;
  1520.   }*/
  1521. ptr += remain;
  1522. }
  1523. }
  1524. b.UnlockBits(bmpData);
  1525. return true;
  1526. }
  1527.  
  1528. }
  1529. }

Structure et Fichiers du projet

Afficher/masquer...


Répertoires contenus dans /var/www/bin/sniplets/bibliobrol/photobrol/model/filters/ 
IcôneNomTailleModification
Pas de sous-répertoires.
IcôneNomTailleModification
| _ Répertoire parent0 octets1732583516 26/11/2024 02:11:56
Fichiers contenus dans /var/www/bin/sniplets/bibliobrol/photobrol/model/filters/ 
IcôneNomTailleModificationAction
IcôneNomTailleModificationAction
Afficher le fichier .cs|.csBitmapFilter.cs41.18 Ko31/10/2018 18:32:51-refusé-
Afficher le fichier .cs|.csConvMatrix.cs592 octets31/10/2018 18:32:51-refusé-
Afficher le fichier .cs|.csFloatPoint.cs219 octets31/10/2018 18:32:51-refusé-

Utilisation de l'explorateur de code

  • Navigation :
    • Un clic sur une icône de répertoire ouvre ce répertoire pour en afficher les fichiers.
    • Lorsque le répertoire en cours ne contient pas de sous-répertoires il est possible de remonter vers le répertoire parent.
    • La structure de répertoires en treetable (tableau en forme d'arborescence) n'est plus possibledans cette version.
    • Un clic sur une icône de fichier ouvre ce fichier pour en afficher le code avec la coloration syntaxique adaptée en fonction du langage principal utilisé dans le fichier.
  • Affichage :
    • Il est possible de trier les répertoires ou les fichiers selon certains critères (nom, taille, date).
  • Actions :
    • Les actions possible sur les fichiers dépendent de vos droits d'utilisateur sur le site. Veuillez activer le mode utilisateur pour activer les actions.

Version en cache

26/11/2024 02:11:56 Cette version de la page est en cache (à la date du 26/11/2024 02:11:56) afin d'accélérer le traitement. Vous pouvez activer le mode utilisateur dans le menu en haut pour afficher la dernère version de la page.

Document créé le 30/10/2009, dernière modification le 26/10/2018
Source du document imprimé : https://www.gaudry.be/cs-photobrol-source-rf-model/filters//BitmapFilter.cs.html

L'infobrol est un site personnel dont le contenu n'engage que moi. Le texte est mis à disposition sous licence CreativeCommons(BY-NC-SA). Plus d'info sur les conditions d'utilisation et sur l'auteur.