PaperSize.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <?php
  2. namespace app\common\library\ps;
  3. /**
  4. * 套打纸张尺寸。坐标用相对整张纸的百分比,毫米和像素用来核对原稿是否铺满纸面。
  5. */
  6. class PaperSize
  7. {
  8. /**
  9. * @return array name => [w_mm, h_mm, px_w@300dpi, px_h@300dpi]
  10. */
  11. public static function presets()
  12. {
  13. return [
  14. 'A4' => [
  15. 'label' => 'A4(210 × 297 mm)',
  16. 'w' => 210,
  17. 'h' => 297,
  18. 'dpi' => 300,
  19. ],
  20. 'A5' => [
  21. 'label' => 'A5(148 × 210 mm)',
  22. 'w' => 148,
  23. 'h' => 210,
  24. 'dpi' => 300,
  25. ],
  26. 'custom' => [
  27. 'label' => '自定义毫米',
  28. 'w' => 210,
  29. 'h' => 297,
  30. 'dpi' => 300,
  31. ],
  32. ];
  33. }
  34. /**
  35. * 300DPI 下的建议像素(整数)。
  36. * @param float $mmW
  37. * @param float $mmH
  38. * @param int $dpi
  39. * @return array
  40. */
  41. public static function pixels($mmW, $mmH, $dpi = 300)
  42. {
  43. $dpi = $dpi > 0 ? (int)$dpi : 300;
  44. return [
  45. 'w' => (int)round($mmW / 25.4 * $dpi),
  46. 'h' => (int)round($mmH / 25.4 * $dpi),
  47. 'dpi' => $dpi,
  48. ];
  49. }
  50. /**
  51. * @param string $name
  52. * @param float $w
  53. * @param float $h
  54. * @return array
  55. */
  56. public static function resolve($name, $w = 0, $h = 0)
  57. {
  58. $name = strtoupper(trim((string)$name));
  59. if ($name === 'CUSTOM' || $name === '自定义') {
  60. $name = 'custom';
  61. }
  62. $presets = self::presets();
  63. if ($name === 'A5') {
  64. $out = $presets['A5'];
  65. $out['name'] = 'A5';
  66. } elseif ($name === 'CUSTOM' || $name === 'custom') {
  67. $out = $presets['custom'];
  68. $out['name'] = 'custom';
  69. if ((float)$w > 0) {
  70. $out['w'] = (float)$w;
  71. }
  72. if ((float)$h > 0) {
  73. $out['h'] = (float)$h;
  74. }
  75. } else {
  76. $out = $presets['A4'];
  77. $out['name'] = 'A4';
  78. }
  79. if ($out['w'] <= 0 || $out['h'] <= 0) {
  80. $out['w'] = 210;
  81. $out['h'] = 297;
  82. $out['name'] = 'A4';
  83. }
  84. $px = self::pixels($out['w'], $out['h'], (int)$out['dpi']);
  85. $out['px_w'] = $px['w'];
  86. $out['px_h'] = $px['h'];
  87. return $out;
  88. }
  89. /**
  90. * 图片高宽比与纸张是否一致(扫描裁切允许少量偏差)。
  91. * @param int $imgW
  92. * @param int $imgH
  93. * @param float $mmW
  94. * @param float $mmH
  95. * @param float $tolerance
  96. * @return bool
  97. */
  98. public static function ratioMatches($imgW, $imgH, $mmW, $mmH, $tolerance = 0.04)
  99. {
  100. if ($imgW < 10 || $imgH < 10 || $mmW <= 0 || $mmH <= 0) {
  101. return false;
  102. }
  103. $imgRatio = $imgH / $imgW;
  104. $paperRatio = $mmH / $mmW;
  105. return abs($imgRatio - $paperRatio) / $paperRatio <= $tolerance;
  106. }
  107. /**
  108. * 按纸张毫米反推当前图的 DPI(取宽边)。
  109. * @param int $imgW
  110. * @param float $mmW
  111. * @return int
  112. */
  113. public static function dpiOf($imgW, $mmW)
  114. {
  115. if ($imgW < 1 || $mmW <= 0) {
  116. return 0;
  117. }
  118. return (int)round($imgW / ($mmW / 25.4));
  119. }
  120. }