Fix ABHA card barcode print rendering

This commit is contained in:
DevSoftTech Server 2026-08-01 03:57:43 +05:30
parent f7a0beadb2
commit ee9bb7b560
2 changed files with 102 additions and 51 deletions

View File

@ -454,6 +454,7 @@ class Abha extends BaseController
$mobileVerified = (int) ($patient['abha_mobile_verified'] ?? 0) === 1;
$abhaQrUrl = 'https://api.qrserver.com/v1/create-qr-code/?size=180x180&data=' . urlencode($abhaNumClean);
$barcodeSvg = $this->buildCode39Svg($hmsId);
$barcodeImage = $this->buildCode39ImageDataUri($hmsId, $barcodeSvg);
return view('abha/card', [
'patient' => $patient,
@ -468,6 +469,7 @@ class Abha extends BaseController
'brand_name' => (string) ($hospitalBrand['brand_name'] ?? 'HMS'),
'hms_id' => $hmsId,
'hms_barcode_svg' => $barcodeSvg,
'hms_barcode_image' => $barcodeImage,
'profile_photo_url' => $profilePhotoUrl,
'abha_qr_url' => $abhaQrUrl,
'patient_mobile' => $mobileNo,
@ -591,10 +593,76 @@ class Abha extends BaseController
}
private function buildCode39Svg(string $value): string
{
$layout = $this->buildCode39Layout($value);
if ($layout === null) {
return '';
}
$rects = [];
foreach ($layout['bars'] as $bar) {
$rects[] = '<rect x="' . $bar['x'] . '" y="0" width="' . $bar['w'] . '" height="' . $layout['height'] . '" fill="#111" />';
}
return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ' . $layout['width'] . ' ' . $layout['height'] . '" role="img" aria-label="HMS Barcode">'
. implode('', $rects)
. '</svg>';
}
private function buildCode39ImageDataUri(string $value, string $svgFallback = ''): string
{
$layout = $this->buildCode39Layout($value);
if ($layout === null) {
return '';
}
if (! function_exists('imagecreatetruecolor') || ! function_exists('imagepng')) {
$svg = $svgFallback !== '' ? $svgFallback : $this->buildCode39Svg($value);
return $svg !== '' ? 'data:image/svg+xml;base64,' . base64_encode($svg) : '';
}
$img = imagecreatetruecolor($layout['width'], $layout['height']);
if ($img === false) {
$svg = $svgFallback !== '' ? $svgFallback : $this->buildCode39Svg($value);
return $svg !== '' ? 'data:image/svg+xml;base64,' . base64_encode($svg) : '';
}
$white = imagecolorallocate($img, 255, 255, 255);
$black = imagecolorallocate($img, 17, 17, 17);
imagefilledrectangle($img, 0, 0, $layout['width'], $layout['height'], $white);
foreach ($layout['bars'] as $bar) {
imagefilledrectangle(
$img,
$bar['x'],
0,
$bar['x'] + $bar['w'] - 1,
$layout['height'],
$black
);
}
ob_start();
imagepng($img);
$pngBinary = ob_get_clean();
imagedestroy($img);
if (! is_string($pngBinary) || $pngBinary === '') {
$svg = $svgFallback !== '' ? $svgFallback : $this->buildCode39Svg($value);
return $svg !== '' ? 'data:image/svg+xml;base64,' . base64_encode($svg) : '';
}
return 'data:image/png;base64,' . base64_encode($pngBinary);
}
/**
* @return array{bars: list<array{x:int,w:int}>, width:int, height:int}|null
*/
private function buildCode39Layout(string $value): ?array
{
$normalized = strtoupper(trim($value));
if ($normalized === '') {
return '';
return null;
}
$supported = [
@ -623,7 +691,7 @@ class Abha extends BaseController
}
if ($clean === '') {
return '';
return null;
}
$narrow = 2;
@ -633,14 +701,14 @@ class Abha extends BaseController
$gap = 2;
$x = $quiet;
$rects = [];
$bars = [];
$cleanLen = strlen($clean);
for ($i = 0; $i < $cleanLen; $i++) {
$pattern = $supported[$clean[$i]];
for ($j = 0; $j < 9; $j++) {
$w = ($pattern[$j] === 'w') ? $wide : $narrow;
if ($j % 2 === 0) {
$rects[] = '<rect x="' . $x . '" y="0" width="' . $w . '" height="' . $height . '" fill="#111" />';
$bars[] = ['x' => $x, 'w' => $w];
}
$x += $w;
}
@ -649,10 +717,11 @@ class Abha extends BaseController
}
}
$width = $x + $quiet;
return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ' . $width . ' ' . $height . '" role="img" aria-label="HMS Barcode">'
. implode('', $rects)
. '</svg>';
return [
'bars' => $bars,
'width' => $x + $quiet,
'height' => $height,
];
}
/**

View File

@ -44,21 +44,20 @@
display: flex;
align-items: center;
gap: 10px;
padding: 6px 10px;
border: 1px solid #d5e4f7;
border-radius: 10px;
background: #f7fbff;
padding: 0;
border: none;
border-radius: 0;
background: transparent;
min-width: 0;
}
.brand-wrap.right { background: #ffffff; }
.brand-wrap.left { justify-content: flex-start; }
.brand-logo {
width: 48px;
height: 48px;
object-fit: contain;
border-radius: 8px;
background: #fff;
border: 1px solid #d7e5f8;
background: transparent;
border: none;
flex: 0 0 auto;
}
.brand-text { min-width: 0; line-height: 1.05; }
@ -76,40 +75,25 @@
margin-bottom: 12px;
display: flex;
align-items: center;
justify-content: space-between;
justify-content: center;
gap: 8px;
}
.hospital-info {
display: flex;
align-items: center;
gap: 8px;
min-width: 0;
}
.hospital-mini-logo {
width: 32px;
height: 32px;
object-fit: contain;
border-radius: 6px;
border: 1px solid #cfe0f8;
background: #fff;
flex: 0 0 auto;
}
.hospital-name {
font-size: 13px;
color: #1e4a82;
min-width: 0;
}
.hospital-name strong { color: #0f3f7d; }
.patient-id-strip {
width: 180px;
width: 100%;
background: #fff;
border: 1px solid #d4e3f8;
border-radius: 8px;
padding: 4px 6px;
padding: 6px 8px;
text-align: center;
flex: 0 0 auto;
flex: 1 1 auto;
min-width: 0;
}
.patient-id-barcode {
display: block;
width: 100%;
height: 28px;
object-fit: contain;
}
.patient-id-strip svg { width: 100%; height: 28px; }
.patient-id-label {
font-size: 9px;
color: #5f7291;
@ -254,7 +238,7 @@ $profilePhotoUrl = (string) ($profile_photo_url ?? '/assets/images/no_image.svg'
$profilePhotoUrlEsc = esc($profilePhotoUrl);
$hmsId = esc($hms_id ?? '');
$abhaQrUrl = esc($abha_qr_url ?? '');
$barcodeSvg = (string) ($hms_barcode_svg ?? '');
$barcodeImage = esc($hms_barcode_image ?? '');
$patientMobile = esc($patient_mobile ?? '');
$mobileVerified = (bool) ($mobile_verified ?? false);
?>
@ -279,19 +263,17 @@ $mobileVerified = (bool) ($mobile_verified ?? false);
</div>
</div>
<div class="hospital-strip">
<div class="hospital-info">
<img class="hospital-mini-logo" src="<?= $hospitalLogo ?>" alt="Hospital Logo">
<div class="hospital-name">Hospital: <strong><?= $hospitalName ?></strong></div>
</div>
<?php if ($barcodeSvg !== '' && $hmsId !== ''): ?>
<?php if ($barcodeImage !== '' && $hmsId !== ''): ?>
<div class="hospital-strip">
<div class="patient-id-strip">
<div class="patient-id-label">Patient ID Barcode</div>
<div><?= $barcodeSvg ?></div>
<?php if ($barcodeImage !== ''): ?>
<img class="patient-id-barcode" src="<?= $barcodeImage ?>" alt="Patient ID Barcode">
<?php endif; ?>
<div class="patient-id-value"><?= $hmsId ?></div>
</div>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<div class="patient-area">
<div>