[{"data":1,"prerenderedAt":1119},["ShallowReactive",2],{"blog-ko-embed-png-transparency":3},{"id":4,"title":5,"author":6,"body":10,"date":1087,"description":1088,"draft":1089,"extension":1090,"howTo":1091,"image":1110,"meta":1111,"navigation":172,"path":1112,"seo":1113,"stem":1114,"tags":1115,"updated":1110,"__hash__":1118},"blogKo/ko/blog/015.embed-png-transparency.md","gpdf 에서 투명 PNG 를 임베드하는 방법",{"name":7,"url":8,"avatar":9},"Taiki Noda","https://nadai.dev/en/about","https://nadai.dev/og-default.png",{"type":11,"value":12,"toc":1076},"minimark",[13,18,27,31,39,136,143,147,154,856,864,868,875,882,899,910,929,933,936,945,951,955,958,972,981,984,988,995,1006,1010,1034,1038,1041,1058,1072],[14,15,17],"h2",{"id":16},"질문을-다시-표현하면","질문을 다시 표현하면",[19,20,21,22,26],"p",{},"로고나 도장을 ",[23,24,25],"strong",{},"배경 투명 PNG"," — Photoshop 이나 Figma 가 내보내는 RGBA PNG — 로 가지고 있다. 이걸 gpdf 의 PDF 에 임베드하면 투명 영역이 그대로 투명으로 남는가? 아니면 로고 주변에 흰색 박스가 생기는가?",[14,28,30],{"id":29},"빠른-답","빠른 답",[19,32,33,34,38],{},"PNG 바이트를 ",[35,36,37],"code",{},"c.Image"," 에 넘기면 끝이다. 추가 옵션은 필요 없다. gpdf 가 알파 채널을 디코드해 PDF SMask (소프트 마스크) 객체를 이미지와 함께 작성한다. 투명 픽셀은 그대로 투명으로 렌더된다.",[40,41,46],"pre",{"className":42,"code":43,"language":44,"meta":45,"style":45},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","logo, _ := os.ReadFile(\"logo.png\")\nc.Image(logo, template.FitWidth(document.Mm(40)))\n","go","",[35,47,48,92],{"__ignoreMap":45},[49,50,53,57,61,64,67,70,73,77,80,83,87,89],"span",{"class":51,"line":52},"line",1,[49,54,56],{"class":55},"sTEyZ","logo",[49,58,60],{"class":59},"sMK4o",",",[49,62,63],{"class":55}," _ ",[49,65,66],{"class":59},":=",[49,68,69],{"class":55}," os",[49,71,72],{"class":59},".",[49,74,76],{"class":75},"s2Zo4","ReadFile",[49,78,79],{"class":59},"(",[49,81,82],{"class":59},"\"",[49,84,86],{"class":85},"sfazB","logo.png",[49,88,82],{"class":59},[49,90,91],{"class":59},")\n",[49,93,95,98,100,103,105,107,109,112,114,117,119,122,124,127,129,133],{"class":51,"line":94},2,[49,96,97],{"class":55},"c",[49,99,72],{"class":59},[49,101,102],{"class":75},"Image",[49,104,79],{"class":59},[49,106,56],{"class":55},[49,108,60],{"class":59},[49,110,111],{"class":55}," template",[49,113,72],{"class":59},[49,115,116],{"class":75},"FitWidth",[49,118,79],{"class":59},[49,120,121],{"class":55},"document",[49,123,72],{"class":59},[49,125,126],{"class":75},"Mm",[49,128,79],{"class":59},[49,130,132],{"class":131},"sbssI","40",[49,134,135],{"class":59},")))\n",[19,137,138,139,142],{},"레시피는 이게 전부. ",[23,140,141],{},"흰 배경에 알파를 평탄화할 필요도, RGBA 를 RGB 로 변환할 필요도, \"투명도 활성화\" 같은 옵션을 넘길 필요도 없다."," PNG 는 PDF 까지 PNG 로 간다.",[14,144,146],{"id":145},"그대로-돌릴-수-있는-완성-예제","그대로 돌릴 수 있는 완성 예제",[19,148,149,150,153],{},"투명도를 실제로 보려면 PNG 아래에 비쳐 보일 무언가가 있어야 한다. 본문 위에 워터마크를 올리는 패턴이 가장 흔하고, ",[35,151,152],{},"page.Absolute"," 는 로고를 고정 좌표에 배치하면서 일반 흐름의 콘텐츠가 그 아래에 페이지를 채우게 해준다.",[40,155,157],{"className":42,"code":156,"language":44,"meta":45,"style":45},"package main\n\nimport (\n    \"log\"\n    \"os\"\n\n    \"github.com/gpdf-dev/gpdf\"\n    \"github.com/gpdf-dev/gpdf/document\"\n    \"github.com/gpdf-dev/gpdf/template\"\n)\n\nfunc main() {\n    stamp, err := os.ReadFile(\"draft-stamp.png\")\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    doc := gpdf.NewDocument(\n        gpdf.WithPageSize(gpdf.A4),\n        gpdf.WithMargins(document.UniformEdges(document.Mm(20))),\n    )\n\n    page := doc.AddPage()\n\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(\"분기 보고서 — 2026 Q1\", template.FontSize(20), template.Bold())\n            c.Text(\"1 분기 매출은 전년 동기 대비 38% 증가했다. 엔터프라이즈 갱신과 금융 서비스 신규 고객 3 곳이 견인했다. 인프라 비용이 정체되며 영업이익률은 24% 까지 확대됐다.\")\n            c.Text(\"분기말 직원은 142 명. 4 분기말 128 명에서 14 명 순증, 그중 9 명이 엔지니어링 채용이다.\")\n        })\n    })\n\n    page.Absolute(document.Mm(60), document.Mm(120), func(c *template.ColBuilder) {\n        c.Image(stamp, template.FitWidth(document.Mm(80)))\n    })\n\n    data, err := doc.Generate()\n    if err != nil {\n        log.Fatal(err)\n    }\n    if err := os.WriteFile(\"report-draft.pdf\", data, 0o644); err != nil {\n        log.Fatal(err)\n    }\n}\n",[35,158,159,168,174,184,196,206,211,221,231,241,246,251,266,296,312,330,336,341,360,384,419,425,430,449,454,488,524,570,590,610,616,622,627,682,720,725,730,751,764,779,784,830,845,850],{"__ignoreMap":45},[49,160,161,164],{"class":51,"line":52},[49,162,163],{"class":59},"package",[49,165,167],{"class":166},"sBMFI"," main\n",[49,169,170],{"class":51,"line":94},[49,171,173],{"emptyLinePlaceholder":172},true,"\n",[49,175,177,181],{"class":51,"line":176},3,[49,178,180],{"class":179},"s7zQu","import",[49,182,183],{"class":59}," (\n",[49,185,187,190,193],{"class":51,"line":186},4,[49,188,189],{"class":59},"    \"",[49,191,192],{"class":166},"log",[49,194,195],{"class":59},"\"\n",[49,197,199,201,204],{"class":51,"line":198},5,[49,200,189],{"class":59},[49,202,203],{"class":166},"os",[49,205,195],{"class":59},[49,207,209],{"class":51,"line":208},6,[49,210,173],{"emptyLinePlaceholder":172},[49,212,214,216,219],{"class":51,"line":213},7,[49,215,189],{"class":59},[49,217,218],{"class":166},"github.com/gpdf-dev/gpdf",[49,220,195],{"class":59},[49,222,224,226,229],{"class":51,"line":223},8,[49,225,189],{"class":59},[49,227,228],{"class":166},"github.com/gpdf-dev/gpdf/document",[49,230,195],{"class":59},[49,232,234,236,239],{"class":51,"line":233},9,[49,235,189],{"class":59},[49,237,238],{"class":166},"github.com/gpdf-dev/gpdf/template",[49,240,195],{"class":59},[49,242,244],{"class":51,"line":243},10,[49,245,91],{"class":59},[49,247,249],{"class":51,"line":248},11,[49,250,173],{"emptyLinePlaceholder":172},[49,252,254,257,260,263],{"class":51,"line":253},12,[49,255,256],{"class":59},"func",[49,258,259],{"class":75}," main",[49,261,262],{"class":59},"()",[49,264,265],{"class":59}," {\n",[49,267,269,272,274,277,279,281,283,285,287,289,292,294],{"class":51,"line":268},13,[49,270,271],{"class":55},"    stamp",[49,273,60],{"class":59},[49,275,276],{"class":55}," err ",[49,278,66],{"class":59},[49,280,69],{"class":55},[49,282,72],{"class":59},[49,284,76],{"class":75},[49,286,79],{"class":59},[49,288,82],{"class":59},[49,290,291],{"class":85},"draft-stamp.png",[49,293,82],{"class":59},[49,295,91],{"class":59},[49,297,299,302,304,307,310],{"class":51,"line":298},14,[49,300,301],{"class":179},"    if",[49,303,276],{"class":55},[49,305,306],{"class":59},"!=",[49,308,309],{"class":59}," nil",[49,311,265],{"class":59},[49,313,315,318,320,323,325,328],{"class":51,"line":314},15,[49,316,317],{"class":55},"        log",[49,319,72],{"class":59},[49,321,322],{"class":75},"Fatal",[49,324,79],{"class":59},[49,326,327],{"class":55},"err",[49,329,91],{"class":59},[49,331,333],{"class":51,"line":332},16,[49,334,335],{"class":59},"    }\n",[49,337,339],{"class":51,"line":338},17,[49,340,173],{"emptyLinePlaceholder":172},[49,342,344,347,349,352,354,357],{"class":51,"line":343},18,[49,345,346],{"class":55},"    doc ",[49,348,66],{"class":59},[49,350,351],{"class":55}," gpdf",[49,353,72],{"class":59},[49,355,356],{"class":75},"NewDocument",[49,358,359],{"class":59},"(\n",[49,361,363,366,368,371,373,376,378,381],{"class":51,"line":362},19,[49,364,365],{"class":55},"        gpdf",[49,367,72],{"class":59},[49,369,370],{"class":75},"WithPageSize",[49,372,79],{"class":59},[49,374,375],{"class":55},"gpdf",[49,377,72],{"class":59},[49,379,380],{"class":55},"A4",[49,382,383],{"class":59},"),\n",[49,385,387,389,391,394,396,398,400,403,405,407,409,411,413,416],{"class":51,"line":386},20,[49,388,365],{"class":55},[49,390,72],{"class":59},[49,392,393],{"class":75},"WithMargins",[49,395,79],{"class":59},[49,397,121],{"class":55},[49,399,72],{"class":59},[49,401,402],{"class":75},"UniformEdges",[49,404,79],{"class":59},[49,406,121],{"class":55},[49,408,72],{"class":59},[49,410,126],{"class":75},[49,412,79],{"class":59},[49,414,415],{"class":131},"20",[49,417,418],{"class":59},"))),\n",[49,420,422],{"class":51,"line":421},21,[49,423,424],{"class":59},"    )\n",[49,426,428],{"class":51,"line":427},22,[49,429,173],{"emptyLinePlaceholder":172},[49,431,433,436,438,441,443,446],{"class":51,"line":432},23,[49,434,435],{"class":55},"    page ",[49,437,66],{"class":59},[49,439,440],{"class":55}," doc",[49,442,72],{"class":59},[49,444,445],{"class":75},"AddPage",[49,447,448],{"class":59},"()\n",[49,450,452],{"class":51,"line":451},24,[49,453,173],{"emptyLinePlaceholder":172},[49,455,457,460,462,465,468,472,475,478,480,483,486],{"class":51,"line":456},25,[49,458,459],{"class":55},"    page",[49,461,72],{"class":59},[49,463,464],{"class":75},"AutoRow",[49,466,467],{"class":59},"(func(",[49,469,471],{"class":470},"sHdIc","r",[49,473,474],{"class":59}," *",[49,476,477],{"class":166},"template",[49,479,72],{"class":59},[49,481,482],{"class":166},"RowBuilder",[49,484,485],{"class":59},")",[49,487,265],{"class":59},[49,489,491,494,496,499,501,504,506,509,511,513,515,517,520,522],{"class":51,"line":490},26,[49,492,493],{"class":55},"        r",[49,495,72],{"class":59},[49,497,498],{"class":75},"Col",[49,500,79],{"class":59},[49,502,503],{"class":131},"12",[49,505,60],{"class":59},[49,507,508],{"class":59}," func(",[49,510,97],{"class":470},[49,512,474],{"class":59},[49,514,477],{"class":166},[49,516,72],{"class":59},[49,518,519],{"class":166},"ColBuilder",[49,521,485],{"class":59},[49,523,265],{"class":59},[49,525,527,530,532,535,537,539,542,544,546,548,550,553,555,557,560,562,564,567],{"class":51,"line":526},27,[49,528,529],{"class":55},"            c",[49,531,72],{"class":59},[49,533,534],{"class":75},"Text",[49,536,79],{"class":59},[49,538,82],{"class":59},[49,540,541],{"class":85},"분기 보고서 — 2026 Q1",[49,543,82],{"class":59},[49,545,60],{"class":59},[49,547,111],{"class":55},[49,549,72],{"class":59},[49,551,552],{"class":75},"FontSize",[49,554,79],{"class":59},[49,556,415],{"class":131},[49,558,559],{"class":59},"),",[49,561,111],{"class":55},[49,563,72],{"class":59},[49,565,566],{"class":75},"Bold",[49,568,569],{"class":59},"())\n",[49,571,573,575,577,579,581,583,586,588],{"class":51,"line":572},28,[49,574,529],{"class":55},[49,576,72],{"class":59},[49,578,534],{"class":75},[49,580,79],{"class":59},[49,582,82],{"class":59},[49,584,585],{"class":85},"1 분기 매출은 전년 동기 대비 38% 증가했다. 엔터프라이즈 갱신과 금융 서비스 신규 고객 3 곳이 견인했다. 인프라 비용이 정체되며 영업이익률은 24% 까지 확대됐다.",[49,587,82],{"class":59},[49,589,91],{"class":59},[49,591,593,595,597,599,601,603,606,608],{"class":51,"line":592},29,[49,594,529],{"class":55},[49,596,72],{"class":59},[49,598,534],{"class":75},[49,600,79],{"class":59},[49,602,82],{"class":59},[49,604,605],{"class":85},"분기말 직원은 142 명. 4 분기말 128 명에서 14 명 순증, 그중 9 명이 엔지니어링 채용이다.",[49,607,82],{"class":59},[49,609,91],{"class":59},[49,611,613],{"class":51,"line":612},30,[49,614,615],{"class":59},"        })\n",[49,617,619],{"class":51,"line":618},31,[49,620,621],{"class":59},"    })\n",[49,623,625],{"class":51,"line":624},32,[49,626,173],{"emptyLinePlaceholder":172},[49,628,630,632,634,637,639,641,643,645,647,650,652,655,657,659,661,664,666,668,670,672,674,676,678,680],{"class":51,"line":629},33,[49,631,459],{"class":55},[49,633,72],{"class":59},[49,635,636],{"class":75},"Absolute",[49,638,79],{"class":59},[49,640,121],{"class":55},[49,642,72],{"class":59},[49,644,126],{"class":75},[49,646,79],{"class":59},[49,648,649],{"class":131},"60",[49,651,559],{"class":59},[49,653,654],{"class":55}," document",[49,656,72],{"class":59},[49,658,126],{"class":75},[49,660,79],{"class":59},[49,662,663],{"class":131},"120",[49,665,559],{"class":59},[49,667,508],{"class":59},[49,669,97],{"class":470},[49,671,474],{"class":59},[49,673,477],{"class":166},[49,675,72],{"class":59},[49,677,519],{"class":166},[49,679,485],{"class":59},[49,681,265],{"class":59},[49,683,685,688,690,692,694,697,699,701,703,705,707,709,711,713,715,718],{"class":51,"line":684},34,[49,686,687],{"class":55},"        c",[49,689,72],{"class":59},[49,691,102],{"class":75},[49,693,79],{"class":59},[49,695,696],{"class":55},"stamp",[49,698,60],{"class":59},[49,700,111],{"class":55},[49,702,72],{"class":59},[49,704,116],{"class":75},[49,706,79],{"class":59},[49,708,121],{"class":55},[49,710,72],{"class":59},[49,712,126],{"class":75},[49,714,79],{"class":59},[49,716,717],{"class":131},"80",[49,719,135],{"class":59},[49,721,723],{"class":51,"line":722},35,[49,724,621],{"class":59},[49,726,728],{"class":51,"line":727},36,[49,729,173],{"emptyLinePlaceholder":172},[49,731,733,736,738,740,742,744,746,749],{"class":51,"line":732},37,[49,734,735],{"class":55},"    data",[49,737,60],{"class":59},[49,739,276],{"class":55},[49,741,66],{"class":59},[49,743,440],{"class":55},[49,745,72],{"class":59},[49,747,748],{"class":75},"Generate",[49,750,448],{"class":59},[49,752,754,756,758,760,762],{"class":51,"line":753},38,[49,755,301],{"class":179},[49,757,276],{"class":55},[49,759,306],{"class":59},[49,761,309],{"class":59},[49,763,265],{"class":59},[49,765,767,769,771,773,775,777],{"class":51,"line":766},39,[49,768,317],{"class":55},[49,770,72],{"class":59},[49,772,322],{"class":75},[49,774,79],{"class":59},[49,776,327],{"class":55},[49,778,91],{"class":59},[49,780,782],{"class":51,"line":781},40,[49,783,335],{"class":59},[49,785,787,789,791,793,795,797,800,802,804,807,809,811,814,816,819,822,824,826,828],{"class":51,"line":786},41,[49,788,301],{"class":179},[49,790,276],{"class":55},[49,792,66],{"class":59},[49,794,69],{"class":55},[49,796,72],{"class":59},[49,798,799],{"class":75},"WriteFile",[49,801,79],{"class":59},[49,803,82],{"class":59},[49,805,806],{"class":85},"report-draft.pdf",[49,808,82],{"class":59},[49,810,60],{"class":59},[49,812,813],{"class":55}," data",[49,815,60],{"class":59},[49,817,818],{"class":131}," 0o644",[49,820,821],{"class":59},");",[49,823,276],{"class":55},[49,825,306],{"class":59},[49,827,309],{"class":59},[49,829,265],{"class":59},[49,831,833,835,837,839,841,843],{"class":51,"line":832},42,[49,834,317],{"class":55},[49,836,72],{"class":59},[49,838,322],{"class":75},[49,840,79],{"class":59},[49,842,327],{"class":55},[49,844,91],{"class":59},[49,846,848],{"class":51,"line":847},43,[49,849,335],{"class":59},[49,851,853],{"class":51,"line":852},44,[49,854,855],{"class":59},"}\n",[19,857,858,860,861,863],{},[35,859,291],{}," 은 빨간 굵은 \"DRAFT\" 글씨에 배경이 완전히 투명한 RGBA PNG 라고 가정한다. 본문 위에 올려지면 모든 투명 픽셀이 아래 단락을 비치게 한다. ",[35,862,291],{}," 을 어떤 로고, 인장, 서명 이미지로 바꿔도 된다 — 같은 코드 경로, 같은 SMask 처리가 돈다.",[14,865,867],{"id":866},"gpdf-가-png-에-실제로-하는-일","gpdf 가 PNG 에 실제로 하는 일",[19,869,870,871,874],{},"흥미로운 건 writer 쪽이다. PDF 에는 \"RGBA 이미지\" 라는 단일 객체가 없다. RGB 이미지 객체와 그에 대응하는 그레이스케일 ",[23,872,873],{},"SMask (소프트 마스크) 이미지"," 가 짝을 이루고, 마스크의 각 픽셀 값이 메인 이미지의 알파로 사용된다. 합성은 PDF 리더가 렌더 시점에 한다.",[19,876,877,878,881],{},"PNG 를 gpdf 에 넘기면 렌더러 (",[35,879,880],{},"document/render/pdftarget.go",") 가 픽셀 격자를 한 번 훑는다:",[883,884,885,889,892],"ul",{},[886,887,888],"li",{},"24 비트 RGB 가 메인 이미지 스트림에 들어가고 FlateDecode 로 압축된다",[886,890,891],{},"8 비트 알파가 별도의 SMask 스트림에 들어가고 역시 FlateDecode 된다",[886,893,894,895,898],{},"이미지 사전에 ",[35,896,897],{},"/SMask \u003Cref>"," 가 추가되어 알파 스트림을 참조한다",[19,900,901,902,905,906,909],{},"모든 알파 샘플이 ",[35,903,904],{},"0xFF"," (완전 불투명) 으로 끝나면 gpdf 는 알파 버퍼를 버리고 SMask 작성을 건너뛴다. ",[23,907,908],{},"JPEG 같은 불투명 PNG 는 결과물에서 추가 비용이 0"," 이라는 뜻. 비용은 알파가 실제로 일을 할 때만 든다.",[19,911,912,913,916,917,920,921,924,925,928],{},"이 경로 전체가 pure Go 다 — 표준 라이브러리의 ",[35,914,915],{},"image/png"," 가 디코드를, ",[35,918,919],{},"compress/flate"," 가 압축을 맡는다. ",[23,922,923],{},"CGO 도, libpng 의존성도 없다."," macOS 에서 ",[35,926,927],{},"linux/arm64"," (Lambda 등) 으로 크로스컴파일해도 결과는 여전히 정적 바이너리 한 개다.",[14,930,932],{"id":931},"jpeg-함정","JPEG 함정",[19,934,935],{},"\"투명한\" 로고가 어떤 도구에서 JPEG 로 내보내졌다면, 투명도는 gpdf 가 그 파일을 보기 전에 이미 사라졌다. JPEG 는 알파 채널을 가질 수 없으므로, 내보낸 도구가 적당한 배경색 (보통 흰색) 으로 알파를 평탄화한 상태다.",[19,937,938,941,942],{},[35,939,940],{},"c.Image(jpegBytes)"," 자체는 잘 동작하지만, 임베드된 이미지는 원래 투명이던 자리에 불투명한 흰색 (혹은 검정, 분홍) 사각형을 남긴다. 수정은 상류에서 — PNG 로 다시 내보내야 한다. ",[23,943,944],{},"gpdf 에는 JPEG 에서 사라진 투명도를 복원하는 옵션이 없다.",[19,946,947,948,950],{},"\"PNG-8\" 의 팔레트 투명도는 별개 이슈다. gpdf 는 표준 ",[35,949,915],{}," 를 쓰므로 팔레트 PNG 도 정상적으로 처리한다. 문제는 자산 파이프라인 어딘가에서 실수로 JPEG 를 거치는 경우 — 한 번 잃어버린 데이터는 돌아오지 않는다.",[14,952,954],{"id":953},"크기-조정과-워터마크","크기 조정과 워터마크",[19,956,957],{},"실용적인 확장은 두 가지로 충분하다.",[19,959,960,963,964,967,968,971],{},[23,961,962],{},"로고 스케일링",": ",[35,965,966],{},"template.FitWidth(document.Mm(40))"," 또는 ",[35,969,970],{},"template.FitHeight(document.Mm(20))"," 을 넘긴다. PNG 는 풀 해상도로 디코드된 뒤, 렌더링 시점에 PDF 좌표 변환으로 축소된다 — 알파에는 리샘플링 단계가 없다. 가장자리는 변함없이 또렷하다.",[19,973,974,977,978,980],{},[23,975,976],{},"대각선 \"DRAFT\" 워터마크",": 워터마크를 알파가 옅은 (25–40% 정도) PNG 로 만들고, 위 예제처럼 ",[35,979,152],{}," 로 배치한다. 알파가 픽셀 단위이므로 워터마크 안에서 불투명도를 변화시키는 것도 가능하다 — 그라디언트 페이드, 로고 실선 주변만 반투명, 같은 식. PDF 리더가 아래 텍스트와 알아서 합성한다.",[19,982,983],{},"픽셀 정확도로 30% 불투명도 오버레이가 필요하면 그건 이미지 편집기에서 알파를 굽는 결정이다. gpdf 는 받은 알파 값을 그대로 재현할 뿐이고, Builder API 에 이미지 단위 불투명도 곱셈 옵션은 없다.",[14,985,987],{"id":986},"파일-크기-감각","파일 크기 감각",[19,989,990,991,994],{},"알파 있는 PNG → RGB 스트림 + 그레이스케일 SMask 스트림이므로 ",[23,992,993],{},"알파 없는 같은 이미지 대비 대략 33% 더 크다",". 100 KB 의 불투명 PNG 임베드는 알파를 붙이면 약 133 KB 가 된다. 로고 한 장이라면 체감되지 않는다. 50 페이지 보고서에 페이지마다 워터마크를 깔아도 마찬가지 — SMask 는 한 번 등록되어 각 페이지에서 참조될 뿐 복제되지 않는다.",[19,996,997,998,1001,1002,1005],{},"이미지 한 장이 갑자기 메가바이트 단위가 된다면 원인은 gpdf 의 인코딩이 아니라 원본 PNG 다. 임베드 전에 ",[35,999,1000],{},"pngquant"," 나 ",[35,1003,1004],{},"oxipng"," 에 한 번 통과시키자. 알파 채널은 두 도구 모두에서 살아남는다.",[14,1007,1009],{"id":1008},"관련-레시피","관련 레시피",[883,1011,1012,1020,1027],{},[886,1013,1014,1019],{},[1015,1016,1018],"a",{"href":1017},"/ko/blog/embed-japanese-font","gpdf 에서 일본어 폰트 임베드하기"," — 같은 \"바이트만 넘기면 된다\" 패턴, TrueType 버전",[886,1021,1022,1026],{},[1015,1023,1025],{"href":1024},"/ko/blog/invoice-pdf-go-under-50-lines","Go 로 50 줄 이내에 인보이스 PDF 만들기"," — 투명 회사 로고가 실제 문서에서 보통 어디에 배치되는지",[886,1028,1029,1033],{},[1015,1030,1032],{"href":1031},"/ko/blog/why-gpdf-is-faster","gpdf 가 다른 Go PDF 라이브러리보다 10–30× 빠른 이유"," — pure Go 디코드 경로가 마이크로초 단위로 무엇을 쓰고 무엇을 절약하는지",[14,1035,1037],{"id":1036},"gpdf-사용해-보기","gpdf 사용해 보기",[19,1039,1040],{},"gpdf 는 Go 의 PDF 생성 라이브러리다. MIT, 의존성 0, PNG 와 TrueType 모두 pure Go 처리.",[40,1042,1046],{"className":1043,"code":1044,"language":1045,"meta":45,"style":45},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[35,1047,1048],{"__ignoreMap":45},[49,1049,1050,1052,1055],{"class":51,"line":52},[49,1051,44],{"class":166},[49,1053,1054],{"class":85}," get",[49,1056,1057],{"class":85}," github.com/gpdf-dev/gpdf\n",[19,1059,1060,1066,1067],{},[1015,1061,1065],{"href":1062,"rel":1063},"https://github.com/gpdf-dev/gpdf",[1064],"nofollow","⭐ Star on GitHub"," · ",[1015,1068,1071],{"href":1069,"rel":1070},"https://gpdf.dev/docs/quickstart",[1064],"Read the docs",[1073,1074,1075],"style",{},"html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":45,"searchDepth":94,"depth":94,"links":1077},[1078,1079,1080,1081,1082,1083,1084,1085,1086],{"id":16,"depth":94,"text":17},{"id":29,"depth":94,"text":30},{"id":145,"depth":94,"text":146},{"id":866,"depth":94,"text":867},{"id":931,"depth":94,"text":932},{"id":953,"depth":94,"text":954},{"id":986,"depth":94,"text":987},{"id":1008,"depth":94,"text":1009},{"id":1036,"depth":94,"text":1037},"2026-04-28","PNG 바이트를 그대로 c.Image 에 넘긴다. gpdf 가 알파 채널을 PDF SMask 로 변환해 투명 배경이 그대로 렌더된다.",false,"md",{"name":1092,"totalTime":1093,"tools":1094,"steps":1097},"gpdf 문서에 알파 채널이 있는 RGBA PNG 임베드하기","PT5M",[1095,1096],"Go 1.22+","알파 채널이 있는 RGBA PNG 파일 (logo.png, stamp.png 등)",[1098,1101,1104,1107],{"name":1099,"text":1100},"PNG 바이트를 읽는다","os.ReadFile 로 PNG 를 []byte 로 읽는다. 바이너리에 자산을 넣고 싶다면 //go:embed 도 가능하다.",{"name":1102,"text":1103},"바이트를 그대로 c.Image 에 넘긴다","컬럼 안에서 c.Image(pngBytes) 를 호출한다. PNG 를 먼저 RGB 로 변환하지 않는다 — 투명도를 재현하려면 gpdf 가 알파 채널을 그대로 받아야 한다.",{"name":1105,"text":1106},"page.Absolute 로 본문 위에 올려 워터마크를 만든다","page.Absolute(x, y, fn) 으로 PNG 를 본문 텍스트 위에 배치한다. 투명 픽셀이 아래 텍스트를 비치게 해 주는 게 워터마크의 본래 목적이다.",{"name":1108,"text":1109},"PNG 가 칼럼보다 크면 FitWidth / FitHeight 로 축소한다","template.FitWidth(document.Mm(40)) 을 넘기면 로고가 비율 그대로 축소된다. 비율이 보존되고, 리샘플링되어도 알파는 살아남는다.",null,{},"/ko/blog/embed-png-transparency",{"title":5,"description":1088},"ko/blog/015.embed-png-transparency",[1116,1117],"recipe","tutorial","HBeOB_hmkkcj_SLOlVI35RWYHs8c4UlebT8fWQbVkuM",1779199026845]