1 year ago
#45792

kientux
Force UIView to draw with specific scale (1 point = 1 pixel)
I'm doing a barcode printing feature, it generates a barcode view and then send the pixels data to the thermal printer. The process is below:
- Snapshot
UIView
with size 250x90 (points) toUIImage
:
let renderer = UIGraphicsImageRenderer(bounds: view.bounds)
let image = renderer.image { rendererContext in
view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
}
- Get pixels data of output image:
extension UIImage {
func pixelData() -> [UInt8]? {
let height = self.size.height
let width = self.size.width
let dataSize = width * height
var pixelData = [UInt8](repeating: 0, count: Int(dataSize))
let colorSpace = CGColorSpaceCreateDeviceGray()
let bitmapInfo: UInt32 = 0
let context = CGContext(data: &pixelData,
width: Int(width),
height: Int(height),
bitsPerComponent: 8,
bytesPerRow: Int(width),
space: colorSpace,
bitmapInfo: bitmapInfo)
guard let cgImage = self.cgImage else { return nil }
context?.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))
return pixelData
}
}
- Send
pixelData
to printer (after some process to convert it to printer data, like which pixel is black/white/gray...)
The problem is that, the size of the output bitmap must be fixed to 250x90 pixels, so it can be fit in the label stamp. But in high resolution iPhones with screen scale of 3x, after called pixelData()
with 250x90 as width/height, the output CGImage
will be downscale from original cgImage
(because the original has 750x270 pixels). And because of downscaling, some black area become gray, and barcode becomes unrecognizable.
I can put the image.scale
to pixelData()
method, but that will make the pixels data to have the physical size of 750x270 pixels and it too large to fit in the label stamp.
I also tried this way to create UIImage
but it still downscales and pixelates the output image:
// force 1.0 scale
UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 1.0)
drawHierarchy(in: bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
So the question is:
- Can I force the
UIView
to be drawn with 1x scale, as 1 point = 1 pixel, and everything after that will working as expected? - Or can I adjust the pixels data generation so that
context.draw
can merge 3 pixels into 1?
ios
uiview
uiimage
cgcontext
cgimage
0 Answers
Your Answer