Split UIImage in half?
You can try this,
UIImage *image = [UIImage imageNamed:@"yourImage.png"];
CGImageRef tmpImgRef = image.CGImage;
CGImageRef topImgRef = CGImageCreateWithImageInRect(tmpImgRef, CGRectMake(0, 0, image.size.width, image.size.height / 2.0));
UIImage *topImage = [UIImage imageWithCGImage:topImgRef];
CGImageRelease(topImgRef);
CGImageRef bottomImgRef = CGImageCreateWithImageInRect(tmpImgRef, CGRectMake(0, image.size.height / 2.0, image.size.width, image.size.height / 2.0));
UIImage *bottomImage = [UIImage imageWithCGImage:bottomImgRef];
CGImageRelease(bottomImgRef);
hope this can help you, :)
Swift 2.2 - Split UIImage by 6X6 small Images
You want a 6/6 grid of images. The code you have divides an image in half. You can't get 1/6ths out of halves. You will need to change the code to give you 6ths. I suggest you write a method that takes as parameters:
- A UIImage.
- A total number of rows
- A total number of columns
- A row index
- A column index
And returns an image at that grid position. It would involve doing some math to calculate the origin and size of the rectangle for that grid position and then uses CGImageCreateWithImageInRect to extract the image in question.
xcode swift how do I split an image?
update: Xcode 8.2.1 • Swift 3.0.2
You can add this extension to split your images:
extension UIImage {
var topHalf: UIImage? {
cgImage?.cropping(
to: CGRect(
origin: .zero,
size: CGSize(width: size.width, height: size.height / 2)
)
)?.image
}
var bottomHalf: UIImage? {
cgImage?.cropping(
to: CGRect(
origin: CGPoint(x: .zero, y: size.height - (size.height/2).rounded()),
size: CGSize(width: size.width, height: size.height - (size.height/2).rounded())
)
)?.image
}
var leftHalf: UIImage? {
cgImage?.cropping(
to: CGRect(
origin: .zero,
size: CGSize(width: size.width/2, height: size.height)
)
)?.image
}
var rightHalf: UIImage? {
cgImage?.cropping(
to: CGRect(
origin: CGPoint(x: size.width - (size.width/2).rounded(), y: .zero),
size: CGSize(width: size.width - (size.width/2).rounded(), height: size.height)
)
)?.image
}
}
extension CGImage {
var image: UIImage { .init(cgImage: self) }
}
Playground testing:
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let imgURL = URL(string: "https://i.stack.imgur.com/Xs4RX.jpg")!
URLSession.shared.dataTask(with: imgURL) { data, response, error in
guard
let data = data, let image = UIImage(data: data)
else { return }
let topHalf = image.topHalf
let bottomHalf = image.bottomHalf
let topLeft = topHalf?.leftHalf
let topRight = topHalf?.rightHalf
let bottomLeft = bottomHalf?.leftHalf
let bottomRight = bottomHalf?.rightHalf
}.resume()
Divide image in array of images with swift
The fundamental issue is the difference between how UIImage
and CGImage
interpret their size
. UIImage
uses "points" and CGImage
uses pixels. And the conversion factor is the scale
.
For example, if a UIImage
has a scale
of 3, every "point" in any given direction the UIImage
, there are three pixels in that direction in the underlying CGImage
. So for a UIImage
that has a scale
of 3 and a size
of 100x100 points, the underlying CGImage
has a size of 300x300 pixels.
To return a simple array of images sliced by n x n (e.g. if n is three, there will be nine images in the array), you can do something like the following in Swift 3:
/// Slice image into array of tiles
///
/// - Parameters:
/// - image: The original image.
/// - howMany: How many rows/columns to slice the image up into.
///
/// - Returns: An array of images.
///
/// - Note: The order of the images that are returned will correspond
/// to the `imageOrientation` of the image. If the image's
/// `imageOrientation` is not `.up`, take care interpreting
/// the order in which the tiled images are returned.
func slice(image: UIImage, into howMany: Int) -> [UIImage] {
let width: CGFloat
let height: CGFloat
switch image.imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
width = image.size.height
height = image.size.width
default:
width = image.size.width
height = image.size.height
}
let tileWidth = Int(width / CGFloat(howMany))
let tileHeight = Int(height / CGFloat(howMany))
let scale = Int(image.scale)
var images = [UIImage]()
let cgImage = image.cgImage!
var adjustedHeight = tileHeight
var y = 0
for row in 0 ..< howMany {
if row == (howMany - 1) {
adjustedHeight = Int(height) - y
}
var adjustedWidth = tileWidth
var x = 0
for column in 0 ..< howMany {
if column == (howMany - 1) {
adjustedWidth = Int(width) - x
}
let origin = CGPoint(x: x * scale, y: y * scale)
let size = CGSize(width: adjustedWidth * scale, height: adjustedHeight * scale)
let tileCgImage = cgImage.cropping(to: CGRect(origin: origin, size: size))!
images.append(UIImage(cgImage: tileCgImage, scale: image.scale, orientation: image.imageOrientation))
x += tileWidth
}
y += tileHeight
}
return images
}
Or, in Swift 2.3:
func slice(image image: UIImage, into howMany: Int) -> [UIImage] {
let width: CGFloat
let height: CGFloat
switch image.imageOrientation {
case .Left, .LeftMirrored, .Right, .RightMirrored:
width = image.size.height
height = image.size.width
default:
width = image.size.width
height = image.size.height
}
let tileWidth = Int(width / CGFloat(howMany))
let tileHeight = Int(height / CGFloat(howMany))
let scale = Int(image.scale)
var images = [UIImage]()
let cgImage = image.CGImage!
var adjustedHeight = tileHeight
var y = 0
for row in 0 ..< howMany {
if row == (howMany - 1) {
adjustedHeight = Int(height) - y
}
var adjustedWidth = tileWidth
var x = 0
for column in 0 ..< howMany {
if column == (howMany - 1) {
adjustedWidth = Int(width) - x
}
let origin = CGPoint(x: x * scale, y: y * scale)
let size = CGSize(width: adjustedWidth * scale, height: adjustedHeight * scale)
let tileCgImage = CGImageCreateWithImageInRect(cgImage, CGRect(origin: origin, size: size))!
images.append(UIImage(CGImage: tileCgImage, scale: image.scale, orientation: image.imageOrientation))
x += tileWidth
}
y += tileHeight
}
return images
}
This makes sure that the resulting images are in the correct scale
(this is why the above strides through the image in "points" and the multiplies to get the correct pixels in the CGImage
). This also, if the dimensions, measured in "points") are not evenly divisible by n, it will making up the difference in the last image for that row or column, respectively. E.g. when you make three tiles for an image with a height of 736 points, the first two will be 245 points, but the last one will be 246 points).
There is one exception that this does not (entirely) handle gracefully. Namely, if the UIImage
has an imageOrientation
of something other than .up
, the order in which the images is retrieved corresponds to that orientation, not the upper left corner of the image as you view it.
UIImage Not Splitting Properly
I used CGImageGetWidth
instead and now it works
CGImageRef topR = CGImageCreateWithImageInRect(imageRef, CGRectMake(0, 0, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)/2));
Spliting a UIImage in half issue in iPad
I was able to solve this using the image.scale option while creating frame and then resizing the resulting image according to my need.
CGImageRef tmpImgRef = myImage.CGImage;
CGImageRef topImgRef = CGImageCreateWithImageInRect(tmpImgRef, CGRectMake(0, 0, myImage.size.width*myImage.scale, (myImage.size.height*myImage.scale)/2));
topImage = [UIImage imageWithCGImage:topImgRef];
CGImageRelease(topImgRef);
CGImageRef bottomImgRef = CGImageCreateWithImageInRect(tmpImgRef, CGRectMake(0, (myImage.size.height*myImage.scale) / 2.0, myImage.size.width*myImage.scale, (myImage.size.height*myImage.scale) / 2.0));
bottomImage = [UIImage imageWithCGImage:bottomImgRef];
CGImageRelease(bottomImgRef);
UIGraphicsGetImageFromCurrentImageContext - Split image into two creates a black background
Try setting the opaque parameter to NO
.
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
How to crop a UIImageView to a new UIImage in 'aspect fill' mode?
Let's divide the problem into two parts:
Given the size of a UIImageView and the size of its UIImage, if the UIImageView's content mode is Aspect Fill, what is the part of the UIImage that fits into the UIImageView? We need, in effect, to crop the original image to match what the UIImageView is actually displaying.
Given an arbitrary rect within the UIImageView, what part of the cropped image (derived in part 1) does it correspond to?
The first part is the interesting part, so let's try it. (The second part will then turn out to be trivial.)
Here's the original image I'll use:
https://static1.squarespace.com/static/54e8ba93e4b07c3f655b452e/t/56c2a04520c64707756f4267/1455596221531/
That image is 1000x611. Here's what it looks like scaled down (but keep in mind that I'm going to be using the original image throughout):
My image view, however, will be 139x182, and is set to Aspect Fill. When it displays the image, it looks like this:
The problem we want to solve is: what part of the original image is being displayed in my image view, if my image view is set to Aspect Fill?
Here we go. Assume that iv
is the image view:
let imsize = iv.image!.size
let ivsize = iv.bounds.size
var scale : CGFloat = ivsize.width / imsize.width
if imsize.height * scale < ivsize.height {
scale = ivsize.height / imsize.height
}
let croppedImsize = CGSize(width:ivsize.width/scale, height:ivsize.height/scale)
let croppedImrect =
CGRect(origin: CGPoint(x: (imsize.width-croppedImsize.width)/2.0,
y: (imsize.height-croppedImsize.height)/2.0),
size: croppedImsize)
So now we have solved the problem: croppedImrect
is the region of the original image that is showing in the image view. Let's proceed to use our knowledge, by actually cropping the image to a new image matching what is shown in the image view:
let r = UIGraphicsImageRenderer(size:croppedImsize)
let croppedIm = r.image { _ in
iv.image!.draw(at: CGPoint(x:-croppedImrect.origin.x, y:-croppedImrect.origin.y))
}
The result is this image (ignore the gray border):
But lo and behold, that is the correct answer! I have extracted from the original image exactly the region portrayed in the interior of the image view.
So now you have all the information you need. croppedIm
is the UIImage actually displayed in the clipped area of the image view. scale
is the scale between the image view and that image. Therefore, you can easily solve the problem you originally proposed! Given any rectangle imposed upon the image view, in the image view's bounds coordinates, you simply apply the scale (i.e. divide all four of its attributes by scale
) — and now you have the same rectangle as a portion of croppedIm
.
(Observe that we didn't really need to crop the original image to get croppedIm
; it was sufficient, in reality, to know how to perform that crop. The important information is the scale
along with the origin
of croppedImRect
; given that information, you can take the rectangle imposed upon the image view, scale it, and offset it to get the desired rectangle of the original image.)
EDIT I added a little screencast just to show that my approach works as a proof of concept:
EDIT Also created a downloadable example project here:
https://github.com/mattneub/Programming-iOS-Book-Examples/blob/39cc800d18aa484d17c26ffcbab8bbe51c614573/bk2ch02p058cropImageView/Cropper/ViewController.swift
But note that I can't guarantee that URL will last forever, so please read the discussion above to understand the approach used.
How to cut an image into 2 using SwiftUI
Here a way of doing this: with using clipped()
modifier.
struct ContentView: View {
@State private var spacing: CGFloat = CGFloat()
@State private var imageSize: CGSize = CGSize()
var body: some View {
let image = Image(systemName: "star")
.resizable()
.scaledToFit()
.frame(width: 200, height: 200, alignment: .center)
.background(Color.yellow)
.cornerRadius(10.0)
.background(GeometryReader { proxy in Color.clear.onAppear() { imageSize = proxy.size } })
return ZStack {
VStack(spacing: spacing) {
image.frame(width: imageSize.width, height: imageSize.height/2, alignment: .top).clipped()
image.frame(width: imageSize.width, height: imageSize.height/2, alignment: .bottom).clipped()
}
VStack { Spacer(); Slider(value: $spacing,in: 0.0...100.0) }
}
.padding()
.compositingGroup()
.shadow(radius: 10.0)
}
}
Related Topics
How to Get the MAC Os X Firewall to Permanently Allow My iOS App
How to Play Movie with a Url Using a Custom Nsurlprotocol
How to Determine If the Sim/Phone Number Has Changed
Uicollectionview Multiple Sections and Headers
How to Get the Result Value of Alamofire.Request().Responsejson in Swift 2
To Change the Color of Unselected Uitabbar Icon in iOS 7
Module 'Alamofire' Has No Member Named 'Request'
Override Uiappearance Property for Mfmailcomposeviewcontroller
How to Draw Inside the Black Edges in iOS Sdk with Opengl Es
Debugging Mobile Safari in iOS 8 and iOS 9
Leaving Inputaccessoryview Visible After Keyboard Is Dismissed
Collectionview with the Horizontal Scroll with Mulitple Section
Restkit and Saving to Coredata as Nsmanagedobject
Pop the Current View Using Segues/Storyboard on iOS 5
Uiview/Calayer: Transform Triggers Layoutsubviews in Superview
How to Do Something Before Unwind Segue Action
Change the Listing Order of the View Controllers in Xcode Storyboard
iOS - Wkwebview Cross Origin Requests Are Only Supported for Http