SKSpriteNode (with texture) with wrong orientation - swift

I have a SpriteKit project with which I'm using Swift to take an image or chose an image and display it. I know how to take or chose the image, but the problem is when I'm displaying it. Whenever I was displaying it, it would have the wrong orientation. So I used this code to orientate it:
let orientedImage = UIImage(CGImage: chosenImage.CGImage!, scale: 1, orientation: chosenImage.imageOrientation)
This worked very well on a UIImageView, but didn't work on a SKSpriteNode. This is the code I have for displaying the image on a UIImageView and on a SKSpriteNode:
let imageview = UIImageView(image: orientedImage) // Displaying the image on a UIImageView
self.view!.addSubview(imageview)
let texture = SKTexture(image: orientedImage)
let node = SKSpriteNode(texture: texture) // Displaying the image on a SKSpriteNode
self.addChild(node)
I have no idea why this doesn't work on a SKSpriteNode, but works on a UIImageView. Please help... Thanks in advance :)

Related

CIGaussianBlur shrinks UIImageView

Using CIGaussianBlur causes UIImageView to apply the blur from the border in, making the image appear to shrink (right image). Using .blur on a SwiftUI view does the opposite; the blur is applied from the border outwards (left image). This is the effect I’m trying to achieve in UIKit. How can I go about this?
I've seen a few posts about using CIAffineClamp, but that causes the blur to stop at the image boarder which is not what I want.
private let context = CIContext()
private let filter = CIFilter(name: "CIGaussianBlur")!
private func createBluredImage(using image: UIImage, value: CGFloat) -> UIImage? {
let beginImage = CIImage(image: image)
filter.setValue(beginImage, forKey: kCIInputImageKey)
filter.setValue(value, forKey: kCIInputRadiusKey)
guard
let outputImage = filter.outputImage,
let cgImage = context.createCGImage(outputImage, from: outputImage.extent)
else {
return nil
}
return UIImage(cgImage: cgImage)
}
When I used CIGaussianBlur I wanted my output image to be contained inside the image frame, so I used CIAffineClamp on the image before applying the blur, as you describe.
You might need to render your source image into a larger frame, clamp to that larger frame using CIAffineClamp, apply your blur filter, then load the resulting blurred output image. Core Image is a bit of a pain to set up and figure out, so I don’t have a full solution ready for you, but that’s what I would suggest.

Rotate downloaded (image.png) before/after saving?

I’m trying to rotate a downloaded image that comes in PNG format with a 4:3 ratio that’s landscape.
I need the image rotated by 90 degrees so it’s portrait with the same dimensions.
I tried the .transform function which worked to start with but doesn’t anymore after adding a scrollView with a lot of settings to allow it to zoom and pan, Id rather not go down the route of editing the srollView content as it took a long time to get all the constrains to work properly to allow free zoom and pan.
After downloading my image I save it to app file. Then it’s loaded for display in another function.
Is it possible to rotate the downloaded file whilst saving so it can be retrieved in the correct way?
I found this in another post which I believe would work with the downloaded image, how can I change the orientation for my need?
func normalizedImage() -> UIImage
{
if (self.imageOrientation == UIImageOrientation.Up) {
return self;
}
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale);
let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
self.drawInRect(rect)
let normalizedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
return normalizedImage;
}
If you display the UIImage in an image view you can try modifying the orientation.
It is basically the same UIImage but with a flag that is interpreted by UIImageView to rotate the image display.
let rotated = UIImage(cgImage: image.cgImage!, scale: 1, orientation: .right)
If you really want to save a new image to disk, you will need to actually redraw the image. Some info is already available here : How to Rotate a UIImage 90 degrees?

How to prevent distorted images?

I have the problem that the images I add are distorted. I have created a pixel accurate background for the iPhone X at (1125 x 2436), so I don't have to use .aspectFill and .aspectFit because I want a screen without black borders.
I use the following code to create the images:
func animateDeck() {
let chip = SKSpriteNode(imageNamed: "Chip")
chip.position = CGPoint(x: 300, y: 400)
chip.zPosition = 2
chip.setScale(1)
gameScene2.addChild(chip)
print("test")
}
Is there a way to display the images in their correct size without using .aspectFit or .aspectFill?
now (left) and how it should be (right)
Thank you in advance!
Check out this project I just made to show you how to create a texture and apply it to a node. All you need should be in GameScene.swift.
Also, in your ViewController, make sure that your GameScene is initialised properly as shown in my project, or how you did it with this:
gameScene2 = GameScene(size: view, bounds: size)

NSView dataWithPDF inside rect but with background view

I wan´t to take a screenshot of a NSView but when I do this, I get an image without the background. All the subviews are show, but not the background. I use this code:
if let image = NSImage(data: background.dataWithPDF(inside: background.bounds)) {
let imageView = NSImageView(image: image)
imageView.imageScaling = .scaleProportionallyUpOrDown
return NSImageView(image: image)
}
I thought, ok when I get only the subviews, then I will make a screenshot of the superview and I thried the following:
if let superview = background.superview, let image = NSImage(data: superview.dataWithPDF(inside: background.frame)) {
let imageView = NSImageView(image: image)
imageView.imageScaling = .scaleProportionallyUpOrDown
return NSImageView(image: image)
}
But I get the same result. Even if I set the background color of my background view I don´t get an image without transparent background.
How can I resolve this?
thank you
Artur
I got an Answer:
background.lockFocus()
if let rep = NSBitmapImageRep(focusedViewRect: background.bounds){
let img = NSImage(size: background.bounds.size)
img.addRepresentation(rep)
return NSImageView(image: img)
}
background.unlockFocus()
You could have converted the views backing layer.backgroundColor to an image. Then assign the image to a backing image view that sits in the 0th index of your views heirarchy and use the method dataWithPDF -> that will successfully capture a background.

UIImageView Image Disappears With Certain UIImageOrientations

Working through a Core Graphics tutorial http://www.raywenderlich.com/76285/beginning-core-image-swift
Theres one part where you need to preserve the UIImageOrientation (of course!). However I'm noticing something VERY quirky and I'm not sure what the cause is.
Here is the code block
#IBAction func amountSliderValueChanged(sender: UISlider) {
let sliderValue = sender.value
filter.setValue(sliderValue, forKey: kCIInputIntensityKey)
let outputImage = filter.outputImage;
let cgimg = context.createCGImage(filter.outputImage, fromRect: filter.outputImage.extent())
let newImage = UIImage(CGImage: cgimg, scale:1, orientation: UIImageOrientation.UpMirrored)
// let newImage = UIImage(CGImage: cgimg)
println("New image is \(newImage)")
self.imageView.image = newImage
}
When I change the image to certain rotations, say Up, the image appears. However when I change to right or left it moves outside the UIImageView (and if I set the scale up really high I can see parts of it coming back on the screen).
I am not rotating the UIImageView, only the UIImage. Before, when I was doing this in Objective-C I never had this issue. I would just set the UIImage rotation and it would always be 0,0 in the UIImageView.
Using Swift (or perhaps something else?) seems to result in different behaviour.
Can you think of any reason why rotating the image moves it way from the its 0,0 of its UIImageView, and what I can do fix that?
Thanks!