[{"data":1,"prerenderedAt":1372},["ShallowReactive",2],{"blog-zh-scale-image-fit-column":3},{"id":4,"title":5,"author":6,"body":10,"date":1341,"description":1342,"draft":1343,"extension":1344,"howTo":1345,"image":1363,"meta":1364,"navigation":207,"path":1365,"seo":1366,"stem":1367,"tags":1368,"updated":1363,"__hash__":1371},"blogZh/zh/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":1330},"minimark",[13,17,37,41,77,88,99,183,186,189,871,882,886,889,970,985,988,991,1067,1073,1079,1164,1167,1170,1177,1180,1186,1254,1259,1262,1290,1294,1297,1314,1326],[14,15,16],"h2",{"id":16},"换个说法的问题",[18,19,20,21,28,29,33,34,36],"p",{},"我有一个 logo、图表或截图 —— 比如 1200×800 的 PNG —— 想放进 ",[22,23,27],"a",{"href":24,"rel":25},"https://github.com/gpdf-dev/gpdf",[26],"nofollow","gpdf"," 的某一列里。我",[30,31,32],"strong",{},"不想","手算宽高比，",[30,35,32],{},"让它被拉成椭圆，也不想让它溢出到下一列。等比缩小到合适大小，搞定，就这些。",[14,38,40],{"id":39},"tldr","TL;DR",[42,43,48],"pre",{"className":44,"code":45,"language":46,"meta":47,"style":47},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","c.Image(imgBytes)\n","go","",[49,50,51],"code",{"__ignoreMap":47},[52,53,56,60,64,68,71,74],"span",{"class":54,"line":55},"line",1,[52,57,59],{"class":58},"sTEyZ","c",[52,61,63],{"class":62},"sMK4o",".",[52,65,67],{"class":66},"s2Zo4","Image",[52,69,70],{"class":62},"(",[52,72,73],{"class":58},"imgBytes",[52,75,76],{"class":62},")\n",[18,78,79,80,83,84,87],{},"最常见的情况下，这就是全部。",[49,81,82],{},"c.Image"," 默认是 ",[49,85,86],{},"FitContain","，会按列宽等比缩放，保持原始宽高比。如果图片本身就比列窄，gpdf 就按原尺寸画出来。",[18,89,90,91,94,95,98],{},"需要比整列更小的边界？加 ",[49,92,93],{},"template.FitWidth"," 或 ",[49,96,97],{},"template.FitHeight","：",[42,100,102],{"className":44,"code":101,"language":46,"meta":47,"style":47},"c.Image(imgBytes, template.FitWidth(document.Mm(40)))\nc.Image(imgBytes, template.FitHeight(document.Mm(20)))\n",[49,103,104,146],{"__ignoreMap":47},[52,105,106,108,110,112,114,116,119,122,124,127,129,132,134,137,139,143],{"class":54,"line":55},[52,107,59],{"class":58},[52,109,63],{"class":62},[52,111,67],{"class":66},[52,113,70],{"class":62},[52,115,73],{"class":58},[52,117,118],{"class":62},",",[52,120,121],{"class":58}," template",[52,123,63],{"class":62},[52,125,126],{"class":66},"FitWidth",[52,128,70],{"class":62},[52,130,131],{"class":58},"document",[52,133,63],{"class":62},[52,135,136],{"class":66},"Mm",[52,138,70],{"class":62},[52,140,142],{"class":141},"sbssI","40",[52,144,145],{"class":62},")))\n",[52,147,149,151,153,155,157,159,161,163,165,168,170,172,174,176,178,181],{"class":54,"line":148},2,[52,150,59],{"class":58},[52,152,63],{"class":62},[52,154,67],{"class":66},[52,156,70],{"class":62},[52,158,73],{"class":58},[52,160,118],{"class":62},[52,162,121],{"class":58},[52,164,63],{"class":62},[52,166,167],{"class":66},"FitHeight",[52,169,70],{"class":62},[52,171,131],{"class":58},[52,173,63],{"class":62},[52,175,136],{"class":66},[52,177,70],{"class":62},[52,179,180],{"class":141},"20",[52,182,145],{"class":62},[18,184,185],{},"两个选项都保持原宽高比。只指定一个维度，另一个由 gpdf 计算。",[14,187,188],{"id":188},"完整示例",[42,190,192],{"className":44,"code":191,"language":46,"meta":47,"style":47},"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        // logo 用窄列，固定 30mm 宽\n        r.Col(3, func(c *template.ColBuilder) {\n            c.Image(logo, template.FitWidth(document.Mm(30)))\n        })\n        // chart 用宽列，默认填满可用宽度\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",[49,193,194,203,209,219,231,241,246,256,266,276,281,286,301,336,352,370,376,405,418,433,438,443,462,485,519,525,530,549,554,588,595,631,669,675,681,713,729,734,740,745,766,779,794,799,845,860,865],{"__ignoreMap":47},[52,195,196,199],{"class":54,"line":55},[52,197,198],{"class":62},"package",[52,200,202],{"class":201},"sBMFI"," main\n",[52,204,205],{"class":54,"line":148},[52,206,208],{"emptyLinePlaceholder":207},true,"\n",[52,210,212,216],{"class":54,"line":211},3,[52,213,215],{"class":214},"s7zQu","import",[52,217,218],{"class":62}," (\n",[52,220,222,225,228],{"class":54,"line":221},4,[52,223,224],{"class":62},"    \"",[52,226,227],{"class":201},"log",[52,229,230],{"class":62},"\"\n",[52,232,234,236,239],{"class":54,"line":233},5,[52,235,224],{"class":62},[52,237,238],{"class":201},"os",[52,240,230],{"class":62},[52,242,244],{"class":54,"line":243},6,[52,245,208],{"emptyLinePlaceholder":207},[52,247,249,251,254],{"class":54,"line":248},7,[52,250,224],{"class":62},[52,252,253],{"class":201},"github.com/gpdf-dev/gpdf",[52,255,230],{"class":62},[52,257,259,261,264],{"class":54,"line":258},8,[52,260,224],{"class":62},[52,262,263],{"class":201},"github.com/gpdf-dev/gpdf/document",[52,265,230],{"class":62},[52,267,269,271,274],{"class":54,"line":268},9,[52,270,224],{"class":62},[52,272,273],{"class":201},"github.com/gpdf-dev/gpdf/template",[52,275,230],{"class":62},[52,277,279],{"class":54,"line":278},10,[52,280,76],{"class":62},[52,282,284],{"class":54,"line":283},11,[52,285,208],{"emptyLinePlaceholder":207},[52,287,289,292,295,298],{"class":54,"line":288},12,[52,290,291],{"class":62},"func",[52,293,294],{"class":66}," main",[52,296,297],{"class":62},"()",[52,299,300],{"class":62}," {\n",[52,302,304,307,309,312,315,318,320,323,325,328,332,334],{"class":54,"line":303},13,[52,305,306],{"class":58},"    logo",[52,308,118],{"class":62},[52,310,311],{"class":58}," err ",[52,313,314],{"class":62},":=",[52,316,317],{"class":58}," os",[52,319,63],{"class":62},[52,321,322],{"class":66},"ReadFile",[52,324,70],{"class":62},[52,326,327],{"class":62},"\"",[52,329,331],{"class":330},"sfazB","logo.png",[52,333,327],{"class":62},[52,335,76],{"class":62},[52,337,339,342,344,347,350],{"class":54,"line":338},14,[52,340,341],{"class":214},"    if",[52,343,311],{"class":58},[52,345,346],{"class":62},"!=",[52,348,349],{"class":62}," nil",[52,351,300],{"class":62},[52,353,355,358,360,363,365,368],{"class":54,"line":354},15,[52,356,357],{"class":58},"        log",[52,359,63],{"class":62},[52,361,362],{"class":66},"Fatal",[52,364,70],{"class":62},[52,366,367],{"class":58},"err",[52,369,76],{"class":62},[52,371,373],{"class":54,"line":372},16,[52,374,375],{"class":62},"    }\n",[52,377,379,382,384,386,388,390,392,394,396,398,401,403],{"class":54,"line":378},17,[52,380,381],{"class":58},"    chart",[52,383,118],{"class":62},[52,385,311],{"class":58},[52,387,314],{"class":62},[52,389,317],{"class":58},[52,391,63],{"class":62},[52,393,322],{"class":66},[52,395,70],{"class":62},[52,397,327],{"class":62},[52,399,400],{"class":330},"chart.png",[52,402,327],{"class":62},[52,404,76],{"class":62},[52,406,408,410,412,414,416],{"class":54,"line":407},18,[52,409,341],{"class":214},[52,411,311],{"class":58},[52,413,346],{"class":62},[52,415,349],{"class":62},[52,417,300],{"class":62},[52,419,421,423,425,427,429,431],{"class":54,"line":420},19,[52,422,357],{"class":58},[52,424,63],{"class":62},[52,426,362],{"class":66},[52,428,70],{"class":62},[52,430,367],{"class":58},[52,432,76],{"class":62},[52,434,436],{"class":54,"line":435},20,[52,437,375],{"class":62},[52,439,441],{"class":54,"line":440},21,[52,442,208],{"emptyLinePlaceholder":207},[52,444,446,449,451,454,456,459],{"class":54,"line":445},22,[52,447,448],{"class":58},"    doc ",[52,450,314],{"class":62},[52,452,453],{"class":58}," gpdf",[52,455,63],{"class":62},[52,457,458],{"class":66},"NewDocument",[52,460,461],{"class":62},"(\n",[52,463,465,468,470,473,475,477,479,482],{"class":54,"line":464},23,[52,466,467],{"class":58},"        gpdf",[52,469,63],{"class":62},[52,471,472],{"class":66},"WithPageSize",[52,474,70],{"class":62},[52,476,27],{"class":58},[52,478,63],{"class":62},[52,480,481],{"class":58},"A4",[52,483,484],{"class":62},"),\n",[52,486,488,490,492,495,497,499,501,504,506,508,510,512,514,516],{"class":54,"line":487},24,[52,489,467],{"class":58},[52,491,63],{"class":62},[52,493,494],{"class":66},"WithMargins",[52,496,70],{"class":62},[52,498,131],{"class":58},[52,500,63],{"class":62},[52,502,503],{"class":66},"UniformEdges",[52,505,70],{"class":62},[52,507,131],{"class":58},[52,509,63],{"class":62},[52,511,136],{"class":66},[52,513,70],{"class":62},[52,515,180],{"class":141},[52,517,518],{"class":62},"))),\n",[52,520,522],{"class":54,"line":521},25,[52,523,524],{"class":62},"    )\n",[52,526,528],{"class":54,"line":527},26,[52,529,208],{"emptyLinePlaceholder":207},[52,531,533,536,538,541,543,546],{"class":54,"line":532},27,[52,534,535],{"class":58},"    page ",[52,537,314],{"class":62},[52,539,540],{"class":58}," doc",[52,542,63],{"class":62},[52,544,545],{"class":66},"AddPage",[52,547,548],{"class":62},"()\n",[52,550,552],{"class":54,"line":551},28,[52,553,208],{"emptyLinePlaceholder":207},[52,555,557,560,562,565,568,572,575,578,580,583,586],{"class":54,"line":556},29,[52,558,559],{"class":58},"    page",[52,561,63],{"class":62},[52,563,564],{"class":66},"AutoRow",[52,566,567],{"class":62},"(func(",[52,569,571],{"class":570},"sHdIc","r",[52,573,574],{"class":62}," *",[52,576,577],{"class":201},"template",[52,579,63],{"class":62},[52,581,582],{"class":201},"RowBuilder",[52,584,585],{"class":62},")",[52,587,300],{"class":62},[52,589,591],{"class":54,"line":590},30,[52,592,594],{"class":593},"sHwdD","        // logo 用窄列，固定 30mm 宽\n",[52,596,598,601,603,606,608,611,613,616,618,620,622,624,627,629],{"class":54,"line":597},31,[52,599,600],{"class":58},"        r",[52,602,63],{"class":62},[52,604,605],{"class":66},"Col",[52,607,70],{"class":62},[52,609,610],{"class":141},"3",[52,612,118],{"class":62},[52,614,615],{"class":62}," func(",[52,617,59],{"class":570},[52,619,574],{"class":62},[52,621,577],{"class":201},[52,623,63],{"class":62},[52,625,626],{"class":201},"ColBuilder",[52,628,585],{"class":62},[52,630,300],{"class":62},[52,632,634,637,639,641,643,646,648,650,652,654,656,658,660,662,664,667],{"class":54,"line":633},32,[52,635,636],{"class":58},"            c",[52,638,63],{"class":62},[52,640,67],{"class":66},[52,642,70],{"class":62},[52,644,645],{"class":58},"logo",[52,647,118],{"class":62},[52,649,121],{"class":58},[52,651,63],{"class":62},[52,653,126],{"class":66},[52,655,70],{"class":62},[52,657,131],{"class":58},[52,659,63],{"class":62},[52,661,136],{"class":66},[52,663,70],{"class":62},[52,665,666],{"class":141},"30",[52,668,145],{"class":62},[52,670,672],{"class":54,"line":671},33,[52,673,674],{"class":62},"        })\n",[52,676,678],{"class":54,"line":677},34,[52,679,680],{"class":593},"        // chart 用宽列，默认填满可用宽度\n",[52,682,684,686,688,690,692,695,697,699,701,703,705,707,709,711],{"class":54,"line":683},35,[52,685,600],{"class":58},[52,687,63],{"class":62},[52,689,605],{"class":66},[52,691,70],{"class":62},[52,693,694],{"class":141},"9",[52,696,118],{"class":62},[52,698,615],{"class":62},[52,700,59],{"class":570},[52,702,574],{"class":62},[52,704,577],{"class":201},[52,706,63],{"class":62},[52,708,626],{"class":201},[52,710,585],{"class":62},[52,712,300],{"class":62},[52,714,716,718,720,722,724,727],{"class":54,"line":715},36,[52,717,636],{"class":58},[52,719,63],{"class":62},[52,721,67],{"class":66},[52,723,70],{"class":62},[52,725,726],{"class":58},"chart",[52,728,76],{"class":62},[52,730,732],{"class":54,"line":731},37,[52,733,674],{"class":62},[52,735,737],{"class":54,"line":736},38,[52,738,739],{"class":62},"    })\n",[52,741,743],{"class":54,"line":742},39,[52,744,208],{"emptyLinePlaceholder":207},[52,746,748,751,753,755,757,759,761,764],{"class":54,"line":747},40,[52,749,750],{"class":58},"    data",[52,752,118],{"class":62},[52,754,311],{"class":58},[52,756,314],{"class":62},[52,758,540],{"class":58},[52,760,63],{"class":62},[52,762,763],{"class":66},"Generate",[52,765,548],{"class":62},[52,767,769,771,773,775,777],{"class":54,"line":768},41,[52,770,341],{"class":214},[52,772,311],{"class":58},[52,774,346],{"class":62},[52,776,349],{"class":62},[52,778,300],{"class":62},[52,780,782,784,786,788,790,792],{"class":54,"line":781},42,[52,783,357],{"class":58},[52,785,63],{"class":62},[52,787,362],{"class":66},[52,789,70],{"class":62},[52,791,367],{"class":58},[52,793,76],{"class":62},[52,795,797],{"class":54,"line":796},43,[52,798,375],{"class":62},[52,800,802,804,806,808,810,812,815,817,819,822,824,826,829,831,834,837,839,841,843],{"class":54,"line":801},44,[52,803,341],{"class":214},[52,805,311],{"class":58},[52,807,314],{"class":62},[52,809,317],{"class":58},[52,811,63],{"class":62},[52,813,814],{"class":66},"WriteFile",[52,816,70],{"class":62},[52,818,327],{"class":62},[52,820,821],{"class":330},"report.pdf",[52,823,327],{"class":62},[52,825,118],{"class":62},[52,827,828],{"class":58}," data",[52,830,118],{"class":62},[52,832,833],{"class":141}," 0o644",[52,835,836],{"class":62},");",[52,838,311],{"class":58},[52,840,346],{"class":62},[52,842,349],{"class":62},[52,844,300],{"class":62},[52,846,848,850,852,854,856,858],{"class":54,"line":847},45,[52,849,357],{"class":58},[52,851,63],{"class":62},[52,853,362],{"class":66},[52,855,70],{"class":62},[52,857,367],{"class":58},[52,859,76],{"class":62},[52,861,863],{"class":54,"line":862},46,[52,864,375],{"class":62},[52,866,868],{"class":54,"line":867},47,[52,869,870],{"class":62},"}\n",[18,872,873,874,877,878,881],{},"3 列宽的 logo 单元格用 ",[49,875,876],{},"FitWidth(30mm)","，因为我们想让 logo 不论列宽多少都保持小而一致。9 列宽的 chart 单元格只用 ",[49,879,880],{},"c.Image(chart)","，让它充分利用列内可用宽度。两个都按比例缩放，代码里都不需要知道源图的像素数。",[14,883,885],{"id":884},"gpdf-中的等比到底指什么","gpdf 中的\"等比\"到底指什么",[18,887,888],{},"总共 4 种 fit 模式，1 种是默认，覆盖大约 90% 的实际需求：",[890,891,892,908],"table",{},[893,894,895],"thead",{},[896,897,898,902,905],"tr",{},[899,900,901],"th",{},"模式",[899,903,904],{},"行为",[899,906,907],{},"适用场景",[909,910,911,925,941,957],"tbody",{},[896,912,913,919,922],{},[914,915,916,918],"td",{},[49,917,86],{}," (默认)",[914,920,921],{},"按比例缩小适配 box，保持宽高比，可能在某一维留白",[914,923,924],{},"logo、图表、截图 —— 几乎全部",[896,926,927,932,938],{},[914,928,929],{},[49,930,931],{},"FitCover",[914,933,934,935],{},"按比例放大或缩小完全覆盖 box，",[30,936,937],{},"裁掉溢出",[914,939,940],{},"hero 横幅、头像方形裁剪",[896,942,943,948,954],{},[914,944,945],{},[49,946,947],{},"FitStretch",[914,949,950,951],{},"完全填满 box，",[30,952,953],{},"会扭曲宽高比",[914,955,956],{},"几乎不用，用了通常是 bug",[896,958,959,964,967],{},[914,960,961],{},[49,962,963],{},"FitOriginal",[914,965,966],{},"按 72 DPI 换算后的源像素尺寸渲染",[914,968,969],{},"按印刷分辨率制作、不能重采样的图",[18,971,972,974,975,977,978,980,981,984],{},[49,973,126],{}," 和 ",[49,976,167],{}," 都是固定一维、另一维用 ",[49,979,86],{}," 算。它们是\"我关心宽度\"或\"我关心高度\"的语法糖 —— 几乎不用直接调 ",[49,982,983],{},"WithFitMode","。",[14,986,987],{"id":987},"容易踩的坑",[18,989,990],{},"最常见的错误是同时给宽和高，且和源宽高比不匹配，然后抱怨图被压扁。比如这种写法：",[42,992,994],{"className":44,"code":993,"language":46,"meta":47,"style":47},"// 除非你真的想这么做，不要写这样的代码\nc.Image(img,\n    template.FitWidth(document.Mm(40)),\n    template.FitHeight(document.Mm(40)),\n)\n",[49,995,996,1001,1017,1041,1063],{"__ignoreMap":47},[52,997,998],{"class":54,"line":55},[52,999,1000],{"class":593},"// 除非你真的想这么做，不要写这样的代码\n",[52,1002,1003,1005,1007,1009,1011,1014],{"class":54,"line":148},[52,1004,59],{"class":58},[52,1006,63],{"class":62},[52,1008,67],{"class":66},[52,1010,70],{"class":62},[52,1012,1013],{"class":58},"img",[52,1015,1016],{"class":62},",\n",[52,1018,1019,1022,1024,1026,1028,1030,1032,1034,1036,1038],{"class":54,"line":211},[52,1020,1021],{"class":58},"    template",[52,1023,63],{"class":62},[52,1025,126],{"class":66},[52,1027,70],{"class":62},[52,1029,131],{"class":58},[52,1031,63],{"class":62},[52,1033,136],{"class":66},[52,1035,70],{"class":62},[52,1037,142],{"class":141},[52,1039,1040],{"class":62},")),\n",[52,1042,1043,1045,1047,1049,1051,1053,1055,1057,1059,1061],{"class":54,"line":221},[52,1044,1021],{"class":58},[52,1046,63],{"class":62},[52,1048,167],{"class":66},[52,1050,70],{"class":62},[52,1052,131],{"class":58},[52,1054,63],{"class":62},[52,1056,136],{"class":66},[52,1058,70],{"class":62},[52,1060,142],{"class":141},[52,1062,1040],{"class":62},[52,1064,1065],{"class":54,"line":233},[52,1066,76],{"class":62},[18,1068,1069,1070,1072],{},"如果 PNG 是 1200×800，硬塞进 40×40 的 box，要么牺牲宽高比 (FitStretch 行为)，要么牺牲一部分图像 (FitCover 行为)。默认 fit 模式是 ",[49,1071,86],{},"，所以 gpdf 会保持比例、让某一维填不满 —— 图片会变成 40mm 宽、约 26mm 高，下方空着 14mm。",[18,1074,1075,1076,1078],{},"修法是只指定一维、信任计算。如果真的需要把非方形图裁成方的，用 ",[49,1077,931],{},"，而不是两个互相矛盾的尺寸：",[42,1080,1082],{"className":44,"code":1081,"language":46,"meta":47,"style":47},"c.Image(img,\n    template.FitWidth(document.Mm(40)),\n    template.FitHeight(document.Mm(40)),\n    template.WithFitMode(document.FitCover),\n)\n",[49,1083,1084,1098,1120,1142,1160],{"__ignoreMap":47},[52,1085,1086,1088,1090,1092,1094,1096],{"class":54,"line":55},[52,1087,59],{"class":58},[52,1089,63],{"class":62},[52,1091,67],{"class":66},[52,1093,70],{"class":62},[52,1095,1013],{"class":58},[52,1097,1016],{"class":62},[52,1099,1100,1102,1104,1106,1108,1110,1112,1114,1116,1118],{"class":54,"line":148},[52,1101,1021],{"class":58},[52,1103,63],{"class":62},[52,1105,126],{"class":66},[52,1107,70],{"class":62},[52,1109,131],{"class":58},[52,1111,63],{"class":62},[52,1113,136],{"class":66},[52,1115,70],{"class":62},[52,1117,142],{"class":141},[52,1119,1040],{"class":62},[52,1121,1122,1124,1126,1128,1130,1132,1134,1136,1138,1140],{"class":54,"line":211},[52,1123,1021],{"class":58},[52,1125,63],{"class":62},[52,1127,167],{"class":66},[52,1129,70],{"class":62},[52,1131,131],{"class":58},[52,1133,63],{"class":62},[52,1135,136],{"class":66},[52,1137,70],{"class":62},[52,1139,142],{"class":141},[52,1141,1040],{"class":62},[52,1143,1144,1146,1148,1150,1152,1154,1156,1158],{"class":54,"line":221},[52,1145,1021],{"class":58},[52,1147,63],{"class":62},[52,1149,983],{"class":66},[52,1151,70],{"class":62},[52,1153,131],{"class":58},[52,1155,63],{"class":62},[52,1157,931],{"class":58},[52,1159,484],{"class":62},[52,1161,1162],{"class":54,"line":233},[52,1163,76],{"class":62},[14,1165,1166],{"id":1166},"像素数不会骗人",[18,1168,1169],{},"gpdf 在做缩放决策前会从 PNG/JPEG header 读取原始像素尺寸。所以把 4000×3000 的照片塞进 60mm 列里，并不是\"在源端缩小\"—— gpdf 把完整字节嵌入 PDF，重采样在 PDF 阅读器渲染时做。无论你把显示尺寸改成多少，输出 PDF 的字节数都一样。",[18,1171,1172,1173,1176],{},"如果文件大小比印刷质量更重要，先用 ",[49,1174,1175],{},"image/draw"," 把源图缩小，再交给 gpdf。库不会替你悄悄丢像素 —— 这个选择留给调用方。",[14,1178,1179],{"id":1179},"应对布局溢出",[18,1181,1182,1183,1185],{},"如果列在渲染时变得比预期窄 —— 比如分页意外断开，或表格单元格收紧适配内容 —— 默认的 ",[49,1184,86],{}," 会乐意把 logo 缩成邮票大小。不想这样，就设个下限：",[42,1187,1189],{"className":44,"code":1188,"language":46,"meta":47,"style":47},"c.Image(logo,\n    template.FitWidth(document.Mm(30)),\n    template.MinDisplayWidth(document.Mm(20)),\n)\n",[49,1190,1191,1205,1227,1250],{"__ignoreMap":47},[52,1192,1193,1195,1197,1199,1201,1203],{"class":54,"line":55},[52,1194,59],{"class":58},[52,1196,63],{"class":62},[52,1198,67],{"class":66},[52,1200,70],{"class":62},[52,1202,645],{"class":58},[52,1204,1016],{"class":62},[52,1206,1207,1209,1211,1213,1215,1217,1219,1221,1223,1225],{"class":54,"line":148},[52,1208,1021],{"class":58},[52,1210,63],{"class":62},[52,1212,126],{"class":66},[52,1214,70],{"class":62},[52,1216,131],{"class":58},[52,1218,63],{"class":62},[52,1220,136],{"class":66},[52,1222,70],{"class":62},[52,1224,666],{"class":141},[52,1226,1040],{"class":62},[52,1228,1229,1231,1233,1236,1238,1240,1242,1244,1246,1248],{"class":54,"line":211},[52,1230,1021],{"class":58},[52,1232,63],{"class":62},[52,1234,1235],{"class":66},"MinDisplayWidth",[52,1237,70],{"class":62},[52,1239,131],{"class":58},[52,1241,63],{"class":62},[52,1243,136],{"class":66},[52,1245,70],{"class":62},[52,1247,180],{"class":141},[52,1249,1040],{"class":62},[52,1251,1252],{"class":54,"line":221},[52,1253,76],{"class":62},[18,1255,1256,1258],{},[49,1257,1235],{}," 告诉布局引擎：如果要把图缩到 20mm 以下才能放下，那就别画在这一页，推到下一页。要么图片清晰可读，要么不画 —— 不会有\"两边都不讨好\"的中间态。",[14,1260,1261],{"id":1261},"相关菜谱",[1263,1264,1265,1276,1283],"ul",{},[1266,1267,1268,1272,1273,1275],"li",{},[22,1269,1271],{"href":1270},"/zh/blog/embed-png-transparency","如何在 gpdf 中嵌入带透明度的 PNG？"," —— 同一个 ",[49,1274,82],{}," 入口，alpha 通道那一面",[1266,1277,1278,1282],{},[22,1279,1281],{"href":1280},"/zh/blog/12-column-grid","gpdf 的 12 列网格如何工作？"," —— \"列宽\"实际会算成多少",[1266,1284,1285,1289],{},[22,1286,1288],{"href":1287},"/zh/blog/table-column-widths","如何设置表格列宽？"," —— 当装图的 box 是表格单元格而不是行的列时",[14,1291,1293],{"id":1292},"试试-gpdf","试试 gpdf",[18,1295,1296],{},"gpdf 是一个 Go 的 PDF 生成库。MIT 协议、零外部依赖、纯 Go 处理图像和字体。",[42,1298,1302],{"className":1299,"code":1300,"language":1301,"meta":47,"style":47},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[49,1303,1304],{"__ignoreMap":47},[52,1305,1306,1308,1311],{"class":54,"line":55},[52,1307,46],{"class":201},[52,1309,1310],{"class":330}," get",[52,1312,1313],{"class":330}," github.com/gpdf-dev/gpdf\n",[18,1315,1316,1320,1321],{},[22,1317,1319],{"href":24,"rel":1318},[26],"⭐ 在 GitHub 上 Star"," · ",[22,1322,1325],{"href":1323,"rel":1324},"https://gpdf.dev/docs/quickstart",[26],"阅读文档",[1327,1328,1329],"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":47,"searchDepth":148,"depth":148,"links":1331},[1332,1333,1334,1335,1336,1337,1338,1339,1340],{"id":16,"depth":148,"text":16},{"id":39,"depth":148,"text":40},{"id":188,"depth":148,"text":188},{"id":884,"depth":148,"text":885},{"id":987,"depth":148,"text":987},{"id":1166,"depth":148,"text":1166},{"id":1179,"depth":148,"text":1179},{"id":1261,"depth":148,"text":1261},{"id":1292,"depth":148,"text":1293},"2026-05-05","把字节传给 c.Image 即可。gpdf 默认按列宽等比缩放。需要明确尺寸时再用 FitWidth / FitHeight。",false,"md",{"name":1346,"totalTime":1347,"tools":1348,"steps":1350},"在 gpdf 列内按比例缩放图片","PT5M",[1349,253],"Go 1.22+",[1351,1354,1357,1360],{"name":1352,"text":1353},"不带任何 fit 选项地调用 c.Image","在 column 内调用 c.Image(imgBytes)。默认 fit 模式是 FitContain，所以 gpdf 会保持原始宽高比，按列宽缩放图片，不需要手动算 width / height。",{"name":1355,"text":1356},"需要小于列宽的固定宽度时用 FitWidth","调用 c.Image(imgBytes, template.FitWidth(document.Mm(40))) 把图片限制为 40mm 宽，高度从源宽高比推导。",{"name":1358,"text":1359},"需要约束高度时用 FitHeight","调用 c.Image(imgBytes, template.FitHeight(document.Mm(20))) 锁定高度为 20mm，宽度按比例自动计算。",{"name":1361,"text":1362},"只有需要非默认行为时才用 WithFitMode","传 template.WithFitMode(document.FitCover) 填满 box 并裁剪溢出，FitStretch 拉伸到完全填满，FitOriginal 用 72 DPI 换算后的原始像素尺寸渲染。",null,{},"/zh/blog/scale-image-fit-column",{"title":5,"description":1342},"zh/blog/020.scale-image-fit-column",[1369,1370],"recipe","tutorial","HBEB2S0zPh2YJiaim3mhnEm2hbbhG8gM0re3W-ZK0NQ",1779199016754]