Closed keremerkan closed 1 year ago
There is a way of doing this already available -- unfortunately not with SVG output tho but CGImage is
If you look at the documentation project (in the Demo
folder) I do this to generate the images for the README.md file
It's not overly elegant (and only supports cgimage elements), but you can do some minor configuration and sizing so that might get you part of the way through.
Adding an SVG version of this would require some time.
eg.
for name in QRCodePupilShapeFactory.shared.availableGeneratorNames.sorted() {
guard
let gen = QRCodePupilShapeFactory.shared.named(name),
let pupilImage = QRCodePupilShapeFactory.shared.image(
pupilGenerator: gen,
dimension: imageSize * 2,
foregroundColor: .black,
backgroundColor: CGColor(gray: 0.9, alpha: 1))
else {
fatalError()
}
let nsImage = NSImage(cgImage: pupilImage, size: CGSize(width: imageSize, height: imageSize))
if let tiff = nsImage.tiffRepresentation, let tiffData = NSBitmapImageRep(data: tiff) {
let pngData = tiffData.representation(using: .png, properties: [:])
try! pngData?.write(to: tempURL.appendingPathComponent("pupil_" + name).appendingPathExtension("png"))
}
}
Well, that is good enough for me. I’ll take a look, thanks! :)
Ah I forgot that I added this in 14.0.0, each of the factories now has a convenience function for generating an array of sample images/generator names that the generator produces.
// Generate sample images for each type
let samples = QRCodePixelShapeFactory.shared.generateSampleImages(
dimension: 200,
foregroundColor: .black,
backgroundColor: .white
)
This basically wraps all of the code that I mentioned above :-)
Just tested this. Working great. Looks like I'll be able to programmatically display the images now. I'd like to suggest another addition to the
@objc func image(
pixelGenerator: QRCodePixelShapeGenerator,
dimension: CGFloat,
foregroundColor: CGColor,
backgroundColor: CGColor? = nil,
isOn: Bool = true
) -> CGImage?
function. I see that you are assigning a custom 7x7 boolMatrix when creating the images. Could you add another variable so that we can pass our own custom bool matrix? This way we can pass a 1x1 or 2x2 bool matrix which will be more suitable for small images in a UITableView. Also a dpi
option would be great here. Even better, a scale
option which can pass UIScreen.main.scale
instead of dpi
, so that the images are always pixel perfect for the screen they are viewed on.
The same applies to the uiImage
function of QRCode(). Instead of
let image = doc.uiImage(CGSize(width: imageSide, height: imageSide), dpi: UIScreen.main.scale*72.0)
we could use something like
let image = doc.uiImage(CGSize(width: imageSide, height: imageSide), scale: UIScreen.main.scale)
Many thanks!
14.0.4 has the ability to set a custom bool matrix when generating the sample pixel image.
I think the QRCode.Document
already has a scale option?
@objc func uiImage(dimension: Int, scale: CGFloat = 1) -> UIImage? {
Currently, the sample image generators only generate CGImage, which has no concept of DPI/scale
If you generate the CGImage at double size, then just set the dpi/scale when you're creating the NSImage/UIImage this should solve your issue.
I think the
QRCode.Document
already has a scale option?@objc func uiImage(dimension: Int, scale: CGFloat = 1) -> UIImage? {
You are right, I have completely missed that. Sorry about it.
You are right, I have completely missed that. Sorry about it.
No problems!
I am adding this as an enhancement suggestion.
The best way to display different eye and pixel options to the user is, to present the supplied images (data*), (eye) and (pupil_) as an example. As Xcode can add svg images to asset catalogs now, if these images were in svg format, the examples would be pixel perfect on every screen.
Another option would be to have an "example" variable or function for the shape objects, which would output a UIImage. This way, we can present the options to the user in a menu or in buttons and set the images of the options programmatically like:
Hope this makes sense.