[{"data":1,"prerenderedAt":1375},["ShallowReactive",2],{"blog-ko-scale-image-fit-column":3},{"id":4,"title":5,"author":6,"body":10,"date":1344,"description":1345,"draft":1346,"extension":1347,"howTo":1348,"image":1366,"meta":1367,"navigation":206,"path":1368,"seo":1369,"stem":1370,"tags":1371,"updated":1366,"__hash__":1374},"blogKo/ko/blog/020.scale-image-fit-column.md","gpdf에서 이미지를 비율 유지로 컬럼에 맞추려면?",{"name":7,"url":8,"avatar":9},"Taiki Noda","https://nadai.dev/en/about","https://nadai.dev/og-default.png",{"type":11,"value":12,"toc":1333},"minimark",[13,18,35,39,75,86,97,181,184,188,870,881,885,888,969,984,988,991,1067,1073,1079,1164,1168,1171,1178,1182,1188,1256,1261,1265,1293,1297,1300,1317,1329],[14,15,17],"h2",{"id":16},"질문을-다시-말하면","질문을 다시 말하면",[19,20,21,22,29,30,34],"p",{},"로고, 차트, 스크린샷 — 예를 들어 1200×800 PNG — 를 ",[23,24,28],"a",{"href":25,"rel":26},"https://github.com/gpdf-dev/gpdf",[27],"nofollow","gpdf"," 컬럼에 넣고 싶다. 가로세로비 계산을 손으로 하고 싶지 ",[31,32,33],"strong",{},"않다",". 타원처럼 늘어나는 것도 싫고, 옆 컬럼으로 넘쳐 흐르는 것도 싫다. 그냥 비율 유지하면서 줄여서 맞추고 끝내고 싶다.",[14,36,38],{"id":37},"한-줄-답","한 줄 답",[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","c.Image(imgBytes)\n","go","",[47,48,49],"code",{"__ignoreMap":45},[50,51,54,58,62,66,69,72],"span",{"class":52,"line":53},"line",1,[50,55,57],{"class":56},"sTEyZ","c",[50,59,61],{"class":60},"sMK4o",".",[50,63,65],{"class":64},"s2Zo4","Image",[50,67,68],{"class":60},"(",[50,70,71],{"class":56},"imgBytes",[50,73,74],{"class":60},")\n",[19,76,77,78,81,82,85],{},"대부분의 경우 이게 전부다. ",[47,79,80],{},"c.Image","의 기본은 ",[47,83,84],{},"FitContain","이고, 가로세로비를 유지한 채 컬럼 너비에 맞춰 축소한다. 이미지가 이미 컬럼보다 작다면 원본 크기로 그대로 그려진다.",[19,87,88,89,92,93,96],{},"컬럼 전체가 아니라 더 작은 한계가 필요하다면 ",[47,90,91],{},"template.FitWidth","나 ",[47,94,95],{},"template.FitHeight","를 추가한다:",[40,98,100],{"className":42,"code":99,"language":44,"meta":45,"style":45},"c.Image(imgBytes, template.FitWidth(document.Mm(40)))\nc.Image(imgBytes, template.FitHeight(document.Mm(20)))\n",[47,101,102,144],{"__ignoreMap":45},[50,103,104,106,108,110,112,114,117,120,122,125,127,130,132,135,137,141],{"class":52,"line":53},[50,105,57],{"class":56},[50,107,61],{"class":60},[50,109,65],{"class":64},[50,111,68],{"class":60},[50,113,71],{"class":56},[50,115,116],{"class":60},",",[50,118,119],{"class":56}," template",[50,121,61],{"class":60},[50,123,124],{"class":64},"FitWidth",[50,126,68],{"class":60},[50,128,129],{"class":56},"document",[50,131,61],{"class":60},[50,133,134],{"class":64},"Mm",[50,136,68],{"class":60},[50,138,140],{"class":139},"sbssI","40",[50,142,143],{"class":60},")))\n",[50,145,147,149,151,153,155,157,159,161,163,166,168,170,172,174,176,179],{"class":52,"line":146},2,[50,148,57],{"class":56},[50,150,61],{"class":60},[50,152,65],{"class":64},[50,154,68],{"class":60},[50,156,71],{"class":56},[50,158,116],{"class":60},[50,160,119],{"class":56},[50,162,61],{"class":60},[50,164,165],{"class":64},"FitHeight",[50,167,68],{"class":60},[50,169,129],{"class":56},[50,171,61],{"class":60},[50,173,134],{"class":64},[50,175,68],{"class":60},[50,177,178],{"class":139},"20",[50,180,143],{"class":60},[19,182,183],{},"둘 다 원본 비율을 유지한다. 한쪽 차원만 지정하면 나머지는 gpdf가 계산한다.",[14,185,187],{"id":186},"실제-예제","실제 예제",[40,189,191],{"className":42,"code":190,"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    logo, err := os.ReadFile(\"logo.png\")\n    if err != nil {\n        log.Fatal(err)\n    }\n    chart, err := os.ReadFile(\"chart.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        // 로고용 좁은 컬럼, 30mm로 고정\n        r.Col(3, func(c *template.ColBuilder) {\n            c.Image(logo, template.FitWidth(document.Mm(30)))\n        })\n        // 차트용 넓은 컬럼, 기본 fit으로 가용 폭 전체 사용\n        r.Col(9, func(c *template.ColBuilder) {\n            c.Image(chart)\n        })\n    })\n\n    data, err := doc.Generate()\n    if err != nil {\n        log.Fatal(err)\n    }\n    if err := os.WriteFile(\"report.pdf\", data, 0o644); err != nil {\n        log.Fatal(err)\n    }\n}\n",[47,192,193,202,208,218,230,240,245,255,265,275,280,285,300,335,351,369,375,404,417,432,437,442,461,484,518,524,529,548,553,587,594,630,668,674,680,712,728,733,739,744,765,778,793,798,844,859,864],{"__ignoreMap":45},[50,194,195,198],{"class":52,"line":53},[50,196,197],{"class":60},"package",[50,199,201],{"class":200},"sBMFI"," main\n",[50,203,204],{"class":52,"line":146},[50,205,207],{"emptyLinePlaceholder":206},true,"\n",[50,209,211,215],{"class":52,"line":210},3,[50,212,214],{"class":213},"s7zQu","import",[50,216,217],{"class":60}," (\n",[50,219,221,224,227],{"class":52,"line":220},4,[50,222,223],{"class":60},"    \"",[50,225,226],{"class":200},"log",[50,228,229],{"class":60},"\"\n",[50,231,233,235,238],{"class":52,"line":232},5,[50,234,223],{"class":60},[50,236,237],{"class":200},"os",[50,239,229],{"class":60},[50,241,243],{"class":52,"line":242},6,[50,244,207],{"emptyLinePlaceholder":206},[50,246,248,250,253],{"class":52,"line":247},7,[50,249,223],{"class":60},[50,251,252],{"class":200},"github.com/gpdf-dev/gpdf",[50,254,229],{"class":60},[50,256,258,260,263],{"class":52,"line":257},8,[50,259,223],{"class":60},[50,261,262],{"class":200},"github.com/gpdf-dev/gpdf/document",[50,264,229],{"class":60},[50,266,268,270,273],{"class":52,"line":267},9,[50,269,223],{"class":60},[50,271,272],{"class":200},"github.com/gpdf-dev/gpdf/template",[50,274,229],{"class":60},[50,276,278],{"class":52,"line":277},10,[50,279,74],{"class":60},[50,281,283],{"class":52,"line":282},11,[50,284,207],{"emptyLinePlaceholder":206},[50,286,288,291,294,297],{"class":52,"line":287},12,[50,289,290],{"class":60},"func",[50,292,293],{"class":64}," main",[50,295,296],{"class":60},"()",[50,298,299],{"class":60}," {\n",[50,301,303,306,308,311,314,317,319,322,324,327,331,333],{"class":52,"line":302},13,[50,304,305],{"class":56},"    logo",[50,307,116],{"class":60},[50,309,310],{"class":56}," err ",[50,312,313],{"class":60},":=",[50,315,316],{"class":56}," os",[50,318,61],{"class":60},[50,320,321],{"class":64},"ReadFile",[50,323,68],{"class":60},[50,325,326],{"class":60},"\"",[50,328,330],{"class":329},"sfazB","logo.png",[50,332,326],{"class":60},[50,334,74],{"class":60},[50,336,338,341,343,346,349],{"class":52,"line":337},14,[50,339,340],{"class":213},"    if",[50,342,310],{"class":56},[50,344,345],{"class":60},"!=",[50,347,348],{"class":60}," nil",[50,350,299],{"class":60},[50,352,354,357,359,362,364,367],{"class":52,"line":353},15,[50,355,356],{"class":56},"        log",[50,358,61],{"class":60},[50,360,361],{"class":64},"Fatal",[50,363,68],{"class":60},[50,365,366],{"class":56},"err",[50,368,74],{"class":60},[50,370,372],{"class":52,"line":371},16,[50,373,374],{"class":60},"    }\n",[50,376,378,381,383,385,387,389,391,393,395,397,400,402],{"class":52,"line":377},17,[50,379,380],{"class":56},"    chart",[50,382,116],{"class":60},[50,384,310],{"class":56},[50,386,313],{"class":60},[50,388,316],{"class":56},[50,390,61],{"class":60},[50,392,321],{"class":64},[50,394,68],{"class":60},[50,396,326],{"class":60},[50,398,399],{"class":329},"chart.png",[50,401,326],{"class":60},[50,403,74],{"class":60},[50,405,407,409,411,413,415],{"class":52,"line":406},18,[50,408,340],{"class":213},[50,410,310],{"class":56},[50,412,345],{"class":60},[50,414,348],{"class":60},[50,416,299],{"class":60},[50,418,420,422,424,426,428,430],{"class":52,"line":419},19,[50,421,356],{"class":56},[50,423,61],{"class":60},[50,425,361],{"class":64},[50,427,68],{"class":60},[50,429,366],{"class":56},[50,431,74],{"class":60},[50,433,435],{"class":52,"line":434},20,[50,436,374],{"class":60},[50,438,440],{"class":52,"line":439},21,[50,441,207],{"emptyLinePlaceholder":206},[50,443,445,448,450,453,455,458],{"class":52,"line":444},22,[50,446,447],{"class":56},"    doc ",[50,449,313],{"class":60},[50,451,452],{"class":56}," gpdf",[50,454,61],{"class":60},[50,456,457],{"class":64},"NewDocument",[50,459,460],{"class":60},"(\n",[50,462,464,467,469,472,474,476,478,481],{"class":52,"line":463},23,[50,465,466],{"class":56},"        gpdf",[50,468,61],{"class":60},[50,470,471],{"class":64},"WithPageSize",[50,473,68],{"class":60},[50,475,28],{"class":56},[50,477,61],{"class":60},[50,479,480],{"class":56},"A4",[50,482,483],{"class":60},"),\n",[50,485,487,489,491,494,496,498,500,503,505,507,509,511,513,515],{"class":52,"line":486},24,[50,488,466],{"class":56},[50,490,61],{"class":60},[50,492,493],{"class":64},"WithMargins",[50,495,68],{"class":60},[50,497,129],{"class":56},[50,499,61],{"class":60},[50,501,502],{"class":64},"UniformEdges",[50,504,68],{"class":60},[50,506,129],{"class":56},[50,508,61],{"class":60},[50,510,134],{"class":64},[50,512,68],{"class":60},[50,514,178],{"class":139},[50,516,517],{"class":60},"))),\n",[50,519,521],{"class":52,"line":520},25,[50,522,523],{"class":60},"    )\n",[50,525,527],{"class":52,"line":526},26,[50,528,207],{"emptyLinePlaceholder":206},[50,530,532,535,537,540,542,545],{"class":52,"line":531},27,[50,533,534],{"class":56},"    page ",[50,536,313],{"class":60},[50,538,539],{"class":56}," doc",[50,541,61],{"class":60},[50,543,544],{"class":64},"AddPage",[50,546,547],{"class":60},"()\n",[50,549,551],{"class":52,"line":550},28,[50,552,207],{"emptyLinePlaceholder":206},[50,554,556,559,561,564,567,571,574,577,579,582,585],{"class":52,"line":555},29,[50,557,558],{"class":56},"    page",[50,560,61],{"class":60},[50,562,563],{"class":64},"AutoRow",[50,565,566],{"class":60},"(func(",[50,568,570],{"class":569},"sHdIc","r",[50,572,573],{"class":60}," *",[50,575,576],{"class":200},"template",[50,578,61],{"class":60},[50,580,581],{"class":200},"RowBuilder",[50,583,584],{"class":60},")",[50,586,299],{"class":60},[50,588,590],{"class":52,"line":589},30,[50,591,593],{"class":592},"sHwdD","        // 로고용 좁은 컬럼, 30mm로 고정\n",[50,595,597,600,602,605,607,610,612,615,617,619,621,623,626,628],{"class":52,"line":596},31,[50,598,599],{"class":56},"        r",[50,601,61],{"class":60},[50,603,604],{"class":64},"Col",[50,606,68],{"class":60},[50,608,609],{"class":139},"3",[50,611,116],{"class":60},[50,613,614],{"class":60}," func(",[50,616,57],{"class":569},[50,618,573],{"class":60},[50,620,576],{"class":200},[50,622,61],{"class":60},[50,624,625],{"class":200},"ColBuilder",[50,627,584],{"class":60},[50,629,299],{"class":60},[50,631,633,636,638,640,642,645,647,649,651,653,655,657,659,661,663,666],{"class":52,"line":632},32,[50,634,635],{"class":56},"            c",[50,637,61],{"class":60},[50,639,65],{"class":64},[50,641,68],{"class":60},[50,643,644],{"class":56},"logo",[50,646,116],{"class":60},[50,648,119],{"class":56},[50,650,61],{"class":60},[50,652,124],{"class":64},[50,654,68],{"class":60},[50,656,129],{"class":56},[50,658,61],{"class":60},[50,660,134],{"class":64},[50,662,68],{"class":60},[50,664,665],{"class":139},"30",[50,667,143],{"class":60},[50,669,671],{"class":52,"line":670},33,[50,672,673],{"class":60},"        })\n",[50,675,677],{"class":52,"line":676},34,[50,678,679],{"class":592},"        // 차트용 넓은 컬럼, 기본 fit으로 가용 폭 전체 사용\n",[50,681,683,685,687,689,691,694,696,698,700,702,704,706,708,710],{"class":52,"line":682},35,[50,684,599],{"class":56},[50,686,61],{"class":60},[50,688,604],{"class":64},[50,690,68],{"class":60},[50,692,693],{"class":139},"9",[50,695,116],{"class":60},[50,697,614],{"class":60},[50,699,57],{"class":569},[50,701,573],{"class":60},[50,703,576],{"class":200},[50,705,61],{"class":60},[50,707,625],{"class":200},[50,709,584],{"class":60},[50,711,299],{"class":60},[50,713,715,717,719,721,723,726],{"class":52,"line":714},36,[50,716,635],{"class":56},[50,718,61],{"class":60},[50,720,65],{"class":64},[50,722,68],{"class":60},[50,724,725],{"class":56},"chart",[50,727,74],{"class":60},[50,729,731],{"class":52,"line":730},37,[50,732,673],{"class":60},[50,734,736],{"class":52,"line":735},38,[50,737,738],{"class":60},"    })\n",[50,740,742],{"class":52,"line":741},39,[50,743,207],{"emptyLinePlaceholder":206},[50,745,747,750,752,754,756,758,760,763],{"class":52,"line":746},40,[50,748,749],{"class":56},"    data",[50,751,116],{"class":60},[50,753,310],{"class":56},[50,755,313],{"class":60},[50,757,539],{"class":56},[50,759,61],{"class":60},[50,761,762],{"class":64},"Generate",[50,764,547],{"class":60},[50,766,768,770,772,774,776],{"class":52,"line":767},41,[50,769,340],{"class":213},[50,771,310],{"class":56},[50,773,345],{"class":60},[50,775,348],{"class":60},[50,777,299],{"class":60},[50,779,781,783,785,787,789,791],{"class":52,"line":780},42,[50,782,356],{"class":56},[50,784,61],{"class":60},[50,786,361],{"class":64},[50,788,68],{"class":60},[50,790,366],{"class":56},[50,792,74],{"class":60},[50,794,796],{"class":52,"line":795},43,[50,797,374],{"class":60},[50,799,801,803,805,807,809,811,814,816,818,821,823,825,828,830,833,836,838,840,842],{"class":52,"line":800},44,[50,802,340],{"class":213},[50,804,310],{"class":56},[50,806,313],{"class":60},[50,808,316],{"class":56},[50,810,61],{"class":60},[50,812,813],{"class":64},"WriteFile",[50,815,68],{"class":60},[50,817,326],{"class":60},[50,819,820],{"class":329},"report.pdf",[50,822,326],{"class":60},[50,824,116],{"class":60},[50,826,827],{"class":56}," data",[50,829,116],{"class":60},[50,831,832],{"class":139}," 0o644",[50,834,835],{"class":60},");",[50,837,310],{"class":56},[50,839,345],{"class":60},[50,841,348],{"class":60},[50,843,299],{"class":60},[50,845,847,849,851,853,855,857],{"class":52,"line":846},45,[50,848,356],{"class":56},[50,850,61],{"class":60},[50,852,361],{"class":64},[50,854,68],{"class":60},[50,856,366],{"class":56},[50,858,74],{"class":60},[50,860,862],{"class":52,"line":861},46,[50,863,374],{"class":60},[50,865,867],{"class":52,"line":866},47,[50,868,869],{"class":60},"}\n",[19,871,872,873,876,877,880],{},"3 컬럼 짜리 로고 셀은 ",[47,874,875],{},"FitWidth(30mm)","으로 고정한다. 컬럼 폭이 어떻게 변해도 로고는 항상 30mm. 9 컬럼 짜리 차트 셀은 ",[47,878,879],{},"c.Image(chart)","만 써서 컬럼이 주는 만큼 다 쓴다. 둘 다 비율 유지. 코드에서 원본 픽셀 수를 알 필요가 없다.",[14,882,884],{"id":883},"gpdf의-비율-유지가-실제로-의미하는-것","gpdf의 \"비율 유지\"가 실제로 의미하는 것",[19,886,887],{},"fit 모드는 4 개. 그중 기본 1 개로 실용 사례의 90%가 끝난다:",[889,890,891,907],"table",{},[892,893,894],"thead",{},[895,896,897,901,904],"tr",{},[898,899,900],"th",{},"모드",[898,902,903],{},"동작",[898,905,906],{},"쓰는 곳",[908,909,910,924,940,956],"tbody",{},[895,911,912,918,921],{},[913,914,915,917],"td",{},[47,916,84],{}," (기본)",[913,919,920],{},"비율 유지하면서 박스 안에 맞춰 축소. 한쪽 차원에 여백이 남을 수 있음",[913,922,923],{},"로고, 차트, 스크린샷 — 거의 전부",[895,925,926,931,937],{},[913,927,928],{},[47,929,930],{},"FitCover",[913,932,933,934],{},"비율 유지하면서 박스 전체를 덮음. ",[31,935,936],{},"넘치는 부분은 잘림",[913,938,939],{},"히어로 배너, 프로필 사진 정사각 크롭",[895,941,942,947,953],{},[913,943,944],{},[47,945,946],{},"FitStretch",[913,948,949,950],{},"박스에 정확히 맞춰 늘림. ",[31,951,952],{},"비율이 망가짐",[913,954,955],{},"거의 안 씀. 쓰면 보통 버그",[895,957,958,963,966],{},[913,959,960],{},[47,961,962],{},"FitOriginal",[913,964,965],{},"72 DPI 환산한 원본 픽셀 크기로 그림",[913,967,968],{},"인쇄 해상도로 만든 도해를 리샘플링 없이 쓰고 싶을 때",[19,970,971,973,974,976,977,979,980,983],{},[47,972,124],{},"와 ",[47,975,165],{},"는 둘 다 한쪽 차원을 고정하고 다른 쪽은 ",[47,978,84],{},"으로 계산한다. \"폭이 신경 쓰임\" 또는 \"높이가 신경 쓰임\"을 자연스럽게 쓰기 위한 단축 형태이고, ",[47,981,982],{},"WithFitMode","를 직접 부를 일은 거의 없다.",[14,985,987],{"id":986},"자주-빠지는-함정","자주 빠지는 함정",[19,989,990],{},"가장 흔한 실수는 비율이 안 맞는 width와 height를 둘 다 지정해놓고 이미지가 짜부라졌다고 불평하는 케이스:",[40,992,994],{"className":42,"code":993,"language":44,"meta":45,"style":45},"// 진심으로 의도한 게 아니면 쓰지 말 것\nc.Image(img,\n    template.FitWidth(document.Mm(40)),\n    template.FitHeight(document.Mm(40)),\n)\n",[47,995,996,1001,1017,1041,1063],{"__ignoreMap":45},[50,997,998],{"class":52,"line":53},[50,999,1000],{"class":592},"// 진심으로 의도한 게 아니면 쓰지 말 것\n",[50,1002,1003,1005,1007,1009,1011,1014],{"class":52,"line":146},[50,1004,57],{"class":56},[50,1006,61],{"class":60},[50,1008,65],{"class":64},[50,1010,68],{"class":60},[50,1012,1013],{"class":56},"img",[50,1015,1016],{"class":60},",\n",[50,1018,1019,1022,1024,1026,1028,1030,1032,1034,1036,1038],{"class":52,"line":210},[50,1020,1021],{"class":56},"    template",[50,1023,61],{"class":60},[50,1025,124],{"class":64},[50,1027,68],{"class":60},[50,1029,129],{"class":56},[50,1031,61],{"class":60},[50,1033,134],{"class":64},[50,1035,68],{"class":60},[50,1037,140],{"class":139},[50,1039,1040],{"class":60},")),\n",[50,1042,1043,1045,1047,1049,1051,1053,1055,1057,1059,1061],{"class":52,"line":220},[50,1044,1021],{"class":56},[50,1046,61],{"class":60},[50,1048,165],{"class":64},[50,1050,68],{"class":60},[50,1052,129],{"class":56},[50,1054,61],{"class":60},[50,1056,134],{"class":64},[50,1058,68],{"class":60},[50,1060,140],{"class":139},[50,1062,1040],{"class":60},[50,1064,1065],{"class":52,"line":232},[50,1066,74],{"class":60},[19,1068,1069,1070,1072],{},"PNG가 1200×800인데 40×40 박스에 억지로 넣으면 둘 중 하나는 깨져야 한다 — 가로세로비 (FitStretch 동작) 아니면 이미지 일부 (FitCover 동작). 기본 fit 모드는 ",[47,1071,84],{},"이라 gpdf는 비율을 유지하면서 한쪽을 못 채운 채로 둔다. 결과는 폭 40mm, 높이 약 26mm. 40mm 짜리 슬롯의 아래쪽 14mm가 비게 된다.",[19,1074,1075,1076,1078],{},"해법은 한쪽 차원만 지정하고 계산은 맡기는 것. 정말 정사각으로 잘라내고 싶다면 모순된 두 차원이 아니라 ",[47,1077,930],{},"를 써야 한다:",[40,1080,1082],{"className":42,"code":1081,"language":44,"meta":45,"style":45},"c.Image(img,\n    template.FitWidth(document.Mm(40)),\n    template.FitHeight(document.Mm(40)),\n    template.WithFitMode(document.FitCover),\n)\n",[47,1083,1084,1098,1120,1142,1160],{"__ignoreMap":45},[50,1085,1086,1088,1090,1092,1094,1096],{"class":52,"line":53},[50,1087,57],{"class":56},[50,1089,61],{"class":60},[50,1091,65],{"class":64},[50,1093,68],{"class":60},[50,1095,1013],{"class":56},[50,1097,1016],{"class":60},[50,1099,1100,1102,1104,1106,1108,1110,1112,1114,1116,1118],{"class":52,"line":146},[50,1101,1021],{"class":56},[50,1103,61],{"class":60},[50,1105,124],{"class":64},[50,1107,68],{"class":60},[50,1109,129],{"class":56},[50,1111,61],{"class":60},[50,1113,134],{"class":64},[50,1115,68],{"class":60},[50,1117,140],{"class":139},[50,1119,1040],{"class":60},[50,1121,1122,1124,1126,1128,1130,1132,1134,1136,1138,1140],{"class":52,"line":210},[50,1123,1021],{"class":56},[50,1125,61],{"class":60},[50,1127,165],{"class":64},[50,1129,68],{"class":60},[50,1131,129],{"class":56},[50,1133,61],{"class":60},[50,1135,134],{"class":64},[50,1137,68],{"class":60},[50,1139,140],{"class":139},[50,1141,1040],{"class":60},[50,1143,1144,1146,1148,1150,1152,1154,1156,1158],{"class":52,"line":220},[50,1145,1021],{"class":56},[50,1147,61],{"class":60},[50,1149,982],{"class":64},[50,1151,68],{"class":60},[50,1153,129],{"class":56},[50,1155,61],{"class":60},[50,1157,930],{"class":56},[50,1159,483],{"class":60},[50,1161,1162],{"class":52,"line":232},[50,1163,74],{"class":60},[14,1165,1167],{"id":1166},"픽셀-수는-거짓말하지-않는다","픽셀 수는 거짓말하지 않는다",[19,1169,1170],{},"gpdf는 스케일 결정을 내리기 전에 PNG / JPEG 헤더에서 원본 픽셀 크기를 읽는다. 그래서 4000×3000 사진을 60mm 컬럼에 넣어도 \"원본에서 줄여서 들어가는\" 게 아니다. gpdf는 원본 바이트 그대로 PDF에 임베드하고, 리샘플링은 PDF 리더가 렌더링할 때 한다. 표시 크기를 어떻게 바꿔도 출력 PDF 크기는 같다.",[19,1172,1173,1174,1177],{},"파일 크기가 인쇄 품질보다 중요하다면 ",[47,1175,1176],{},"image/draw"," 같은 걸로 먼저 다운샘플링하고 gpdf에 넘긴다. 라이브러리가 알아서 픽셀을 버리지는 않는다 — 그건 호출자가 정할 일이다.",[14,1179,1181],{"id":1180},"레이아웃-오버플로-대비","레이아웃 오버플로 대비",[19,1183,1184,1185,1187],{},"페이지 분할이나 좁아진 테이블 셀 때문에 컬럼이 예상보다 좁아지면, 기본 ",[47,1186,84],{},"은 로고를 우표 크기까지 줄여버린다. 그게 싫으면 하한을 정한다:",[40,1189,1191],{"className":42,"code":1190,"language":44,"meta":45,"style":45},"c.Image(logo,\n    template.FitWidth(document.Mm(30)),\n    template.MinDisplayWidth(document.Mm(20)),\n)\n",[47,1192,1193,1207,1229,1252],{"__ignoreMap":45},[50,1194,1195,1197,1199,1201,1203,1205],{"class":52,"line":53},[50,1196,57],{"class":56},[50,1198,61],{"class":60},[50,1200,65],{"class":64},[50,1202,68],{"class":60},[50,1204,644],{"class":56},[50,1206,1016],{"class":60},[50,1208,1209,1211,1213,1215,1217,1219,1221,1223,1225,1227],{"class":52,"line":146},[50,1210,1021],{"class":56},[50,1212,61],{"class":60},[50,1214,124],{"class":64},[50,1216,68],{"class":60},[50,1218,129],{"class":56},[50,1220,61],{"class":60},[50,1222,134],{"class":64},[50,1224,68],{"class":60},[50,1226,665],{"class":139},[50,1228,1040],{"class":60},[50,1230,1231,1233,1235,1238,1240,1242,1244,1246,1248,1250],{"class":52,"line":210},[50,1232,1021],{"class":56},[50,1234,61],{"class":60},[50,1236,1237],{"class":64},"MinDisplayWidth",[50,1239,68],{"class":60},[50,1241,129],{"class":56},[50,1243,61],{"class":60},[50,1245,134],{"class":64},[50,1247,68],{"class":60},[50,1249,178],{"class":139},[50,1251,1040],{"class":60},[50,1253,1254],{"class":52,"line":220},[50,1255,74],{"class":60},[19,1257,1258,1260],{},[47,1259,1237],{},"는 레이아웃 엔진에 \"20mm 이하로 줄여야 들어간다면 이 페이지에 그리지 말고 다음 페이지로 보내라\"고 말한다. 읽을 수 있는 크기로 그리거나, 아예 그리지 않거나 — 어중간한 중간 상태는 없다.",[14,1262,1264],{"id":1263},"관련-레시피","관련 레시피",[1266,1267,1268,1279,1286],"ul",{},[1269,1270,1271,1275,1276,1278],"li",{},[23,1272,1274],{"href":1273},"/ko/blog/embed-png-transparency","gpdf에서 투명 PNG를 임베드하는 방법"," — 같은 ",[47,1277,80],{}," 입구, 알파 채널 쪽 이야기",[1269,1280,1281,1285],{},[23,1282,1284],{"href":1283},"/ko/blog/12-column-grid","gpdf의 12 컬럼 그리드 동작 방식"," — \"컬럼 폭\"이 실제로 몇 mm가 되는지",[1269,1287,1288,1292],{},[23,1289,1291],{"href":1290},"/ko/blog/table-column-widths","테이블 컬럼 폭 지정 방법"," — 이미지 들어가는 박스가 행의 컬럼이 아니라 테이블 셀일 때",[14,1294,1296],{"id":1295},"gpdf-써보기","gpdf 써보기",[19,1298,1299],{},"gpdf는 Go의 PDF 생성 라이브러리. MIT, 외부 의존성 0, 이미지와 폰트를 순수 Go로 처리.",[40,1301,1305],{"className":1302,"code":1303,"language":1304,"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",[47,1306,1307],{"__ignoreMap":45},[50,1308,1309,1311,1314],{"class":52,"line":53},[50,1310,44],{"class":200},[50,1312,1313],{"class":329}," get",[50,1315,1316],{"class":329}," github.com/gpdf-dev/gpdf\n",[19,1318,1319,1323,1324],{},[23,1320,1322],{"href":25,"rel":1321},[27],"⭐ GitHub에서 Star"," · ",[23,1325,1328],{"href":1326,"rel":1327},"https://gpdf.dev/docs/quickstart",[27],"문서 보기",[1330,1331,1332],"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 .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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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 .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":45,"searchDepth":146,"depth":146,"links":1334},[1335,1336,1337,1338,1339,1340,1341,1342,1343],{"id":16,"depth":146,"text":17},{"id":37,"depth":146,"text":38},{"id":186,"depth":146,"text":187},{"id":883,"depth":146,"text":884},{"id":986,"depth":146,"text":987},{"id":1166,"depth":146,"text":1167},{"id":1180,"depth":146,"text":1181},{"id":1263,"depth":146,"text":1264},{"id":1295,"depth":146,"text":1296},"2026-05-05","c.Image에 바이트만 넘기면 gpdf가 컬럼 너비에 비율 유지로 맞춘다. 명시적 크기는 FitWidth / FitHeight를 쓴다.",false,"md",{"name":1349,"totalTime":1350,"tools":1351,"steps":1353},"gpdf 컬럼 안에서 이미지를 비율 유지로 스케일링하기","PT5M",[1352,252],"Go 1.22+",[1354,1357,1360,1363],{"name":1355,"text":1356},"fit 옵션 없이 c.Image에 바이트 넘기기","ColBuilder 안에서 c.Image(imgBytes)를 호출한다. 기본 fit 모드가 FitContain이므로 gpdf가 가로세로비를 유지한 채 컬럼 너비에 맞춘다. width / height를 손으로 계산할 필요가 없다.",{"name":1358,"text":1359},"컬럼보다 작은 폭이 필요하면 FitWidth","c.Image(imgBytes, template.FitWidth(document.Mm(40)))로 폭을 40mm로 고정한다. 높이는 원본 비율에서 자동 계산된다.",{"name":1361,"text":1362},"세로 제약이 더 중요하면 FitHeight","c.Image(imgBytes, template.FitHeight(document.Mm(20)))로 높이를 20mm에 고정한다. 폭은 비율에서 계산된다.",{"name":1364,"text":1365},"기본 동작이 부족할 때만 WithFitMode","template.WithFitMode(document.FitCover)는 박스를 채우고 넘치는 부분을 잘라낸다. FitStretch는 비율을 무시하고 정확히 채우고, FitOriginal은 72 DPI로 환산한 원본 픽셀 크기로 그린다.",null,{},"/ko/blog/scale-image-fit-column",{"title":5,"description":1345},"ko/blog/020.scale-image-fit-column",[1372,1373],"recipe","tutorial","nJhKtE4BQ_U-MoWpa5AzQZYa3jp2O0Z6JMCe3UcRtzE",1779199026787]