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 octets1734975270 23/12/2024 18:34: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.

Deutsche Übersetzung

Sie haben gebeten, diese Seite auf Deutsch zu besuchen. Momentan ist nur die Oberfläche übersetzt, aber noch nicht der gesamte Inhalt.

Wenn Sie mir bei Übersetzungen helfen wollen, ist Ihr Beitrag willkommen. Alles, was Sie tun müssen, ist, sich auf der Website zu registrieren und mir eine Nachricht zu schicken, in der Sie gebeten werden, Sie der Gruppe der Übersetzer hinzuzufügen, die Ihnen die Möglichkeit gibt, die gewünschten Seiten zu übersetzen. Ein Link am Ende jeder übersetzten Seite zeigt an, dass Sie der Übersetzer sind und einen Link zu Ihrem Profil haben.

Vielen Dank im Voraus.

Dokument erstellt 30/10/2009, zuletzt geändert 26/10/2018
Quelle des gedruckten Dokuments:https://www.gaudry.be/de/cs-photobrol-source-rf-model/filters//BitmapFilter.cs.html

Die Infobro ist eine persönliche Seite, deren Inhalt in meiner alleinigen Verantwortung liegt. Der Text ist unter der CreativeCommons-Lizenz (BY-NC-SA) verfügbar. Weitere Informationen auf die Nutzungsbedingungen und dem Autor.