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 octets1732230570 22/11/2024 00:09:30
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.

Nederlandse vertaling

U hebt gevraagd om deze site in het Nederlands te bezoeken. Voor nu wordt alleen de interface vertaald, maar nog niet alle inhoud.

Als je me wilt helpen met vertalingen, is je bijdrage welkom. Het enige dat u hoeft te doen, is u op de site registreren en mij een bericht sturen waarin u wordt gevraagd om u toe te voegen aan de groep vertalers, zodat u de gewenste pagina's kunt vertalen. Een link onderaan elke vertaalde pagina geeft aan dat u de vertaler bent en heeft een link naar uw profiel.

Bij voorbaat dank.

Document heeft de 30/10/2009 gemaakt, de laatste keer de 26/10/2018 gewijzigd
Bron van het afgedrukte document:https://www.gaudry.be/nl/cs-photobrol-source-rf-model/filters/BitmapFilter.cs.html

De infobrol is een persoonlijke site waarvan de inhoud uitsluitend mijn verantwoordelijkheid is. De tekst is beschikbaar onder CreativeCommons-licentie (BY-NC-SA). Meer info op de gebruiksvoorwaarden en de auteur.