在 iOS 開發中實現圓形頭像裁剪時,許多開發者發現:即使原圖寬高不等(矩形),裁剪結果依然是完美的正圓。關鍵在於 UIGraphicsBeginImageContextWithOptions 的第一個參數 size 的設置。
// 錯誤示範:直接使用原圖尺寸
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0.0);
// 裁剪邏輯...
若傳入 image.size(如 200×100),繪圖上下文畫布就是 200×100 的矩形。後續繪製圓形路徑 UIBezierPath(ovalIn: rect) 時,rect 通常取畫布中心正方形區域,但畫布本身是矩形,導致輸出圖片包含透明邊緣,視覺上可能被拉伸顯示。
// 取較小邊長作為正方形尺寸
CGFloat side = MIN(image.size.width, image.size.height);
CGSize squareSize = CGSizeMake(side, side);
// 創建正方形繪圖上下文
UIGraphicsBeginImageContextWithOptions(squareSize, NO, 0.0);
// 計算原圖在正方形畫布上的繪製區域(居中裁剪)
CGFloat x = (side - image.size.width) / 2.0;
CGFloat y = (side - image.size.height) / 2.0;
[image drawInRect:CGRectMake(x, y, image.size.width, image.size.height)];
// 裁剪圓形路徑
UIBezierPath *circularPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, side, side)];
[circularPath addClip];
// 獲取結果
UIImage *circularImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsBeginImageContextWithOptions 的 size 參數直接決定最終 UIImage 的像素寬高addClip() 後續繪製內容僅保留路徑內部drawInRect: 可將原圖任意位置、縮放繪製到畫布上只要保證畫布是正方形,裁剪路徑是內切圓,無論原圖比例如何,輸出永遠是完美正圓頭像。