I need help this time. :lol:
I want to split an image (png, for example) into N x N images of the same format and save them in the desktop’s “SlicedImage” folder. I found Objective C handler on the net that works with UIImage, but I find it difficult to translate it into NSImage + AsObjC code so far. The code itself is as follows:
-(NSMutableArray *)getImagesFromImage:(UIImage *)image withRow:(NSInteger)rows withColumn: (NSInteger)columns
{
NSMutableArray *images = [NSMutableArray array];
CGSize imageSize = image.size;
CGFloat xPos = 0.0, yPos = 0.0;
CGFloat width = imageSize.width/rows;
CGFloat height = imageSize.height/columns;
for (int y = 0; y < columns; y++) {
xPos = 0.0;
for (int x = 0; x < rows; x++) {
You can’t use CGImageRefs with ASObjC. UIImage is like NSImage, but you’re probably better off using an image rep.
This is incomplete and untested, but should get you started:
use framework "Foundation"
use framework "AppKit"
use scripting additions
set theImageRep to current application's NSBitmapImageRep's imageRepWithContentsOfFile:imagePath -- load the file as an NSImage
-- Extract its original size and color space
set oldHeight to theImageRep's pixelsHigh()
set oldWidth to theImageRep's pixelsWide()
set spaceName to theImageRep's colorSpaceName()
set theWidth to oldWidth / rows
set theHeight to oldHeight / columns
repeat with i from 1 to rows
setxPos to (i - 1) * theWidth
repeat with j from 1 to columns
setyPos to oldHeight - (j - 1) * theHeight
set newRep to (current application's NSBitmapImageRep's alloc()'s initWithBitmapDataPlanes:(missing value) pixelsWide:theWidth pixelsHigh:theHeight bitsPerSample:8 samplesPerPixel:4 hasAlpha:yes isPlanar:false colorSpaceName:spaceName bitmapFormat:(current application's NSAlphaFirstBitmapFormat) bytesPerRow:0 bitsPerPixel:32)
current application's NSGraphicsContext's saveGraphicsState()
-- set graphics context to new context based on the new bitmapImageRep
(current application's NSGraphicsContext's setCurrentContext:(current application's NSGraphicsContext's graphicsContextWithBitmapImageRep:newRep))
(theImageRep's drawInRect:{{0, 0}, {theWidth, theHeight}} fromRect:{{xPos, yPos}, {theWidth, theHeight}} operation:(current application's NSCompositeSourceOver) fraction:1.0 respectFlipped:false hints:(missing value))
-- restore state
current application's NSGraphicsContext's restoreGraphicsState()
-- save new file
set theData to (newRep's representationUsingType:(current application's NSJPEGFileType) |properties|:{NSImageCompressionFactor:compFactor})
set outPath to ... -- whatever
(theData's writeToFile:outPath atomically:true)
end repeat
end repeat
Oh, Shane! Your AsObjC publications are just an inexhaustible source of new knowledge for me. Thank you very much.
I added routine things here (folders, etc.). The script is almost working. It remains to find an error with the definition of xPos, yPos in the repeat loops. I will try to find it myself, but any help is appreciated too. While the script is like this:
use framework "Foundation"
use framework "AppKit"
use scripting additions
property rows : 2
property columns : 2
property compFactor : 0.8
set imageFile to (choose file of type "public.image")
set imagePath to POSIX path of (imageFile)
tell application "Finder"
if not (exists folder (((path to desktop) as text) & "SlicedImage:")) then
make new folder at desktop with properties {name:"SlicedImage"}
end if
set imageName to name of imageFile
set ext to name extension of imageFile
end tell
set baseName to (current application's NSString's stringWithString:imagePath)'s lastPathComponent()'s stringByDeletingPathExtension() as text
set outPath to POSIX path of (path to desktop) & "SlicedImage/" & baseName
set theImageRep to current application's NSBitmapImageRep's imageRepWithContentsOfFile:imagePath -- load the file as an NSImage
-- Extract its original size and color space
set oldHeight to theImageRep's pixelsHigh()
set oldWidth to theImageRep's pixelsWide()
set spaceName to theImageRep's colorSpaceName()
set theWidth to oldWidth / rows
set theHeight to oldHeight / columns
set counter to 0
repeat with i from 1 to rows
set xPos to (i - 1) * theWidth
repeat with j from 1 to columns
set counter to counter + 1
set yPos to (j - 1) * theHeight
set newRep to (current application's NSBitmapImageRep's alloc()'s initWithBitmapDataPlanes:(missing value) pixelsWide:theWidth pixelsHigh:theHeight bitsPerSample:8 samplesPerPixel:4 hasAlpha:yes isPlanar:false colorSpaceName:spaceName bitmapFormat:(current application's NSAlphaFirstBitmapFormat) bytesPerRow:0 bitsPerPixel:32)
current application's NSGraphicsContext's saveGraphicsState()
-- set graphics context to new context based on the new bitmapImageRep
(current application's NSGraphicsContext's setCurrentContext:(current application's NSGraphicsContext's graphicsContextWithBitmapImageRep:newRep))
(theImageRep's drawInRect:{{0, 0}, {theWidth, theHeight}} fromRect:{{xPos, yPos}, {theWidth, theHeight}} operation:(current application's NSCompositeSourceOver) fraction:1.0 respectFlipped:false hints:(missing value))
-- restore state
current application's NSGraphicsContext's restoreGraphicsState()
-- save new file
set theData to (newRep's representationUsingType:(current application's NSJPEGFileType) |properties|:{NSImageCompressionFactor:compFactor})
(theData's writeToFile:(outPath & "_" & counter & "." & ext) atomically:true)
end repeat
end repeat
Sorry for the delay in answering.
I just got home from work and checked out the fix you suggested. I am very pleased to inform you that the script now works just fine. What is solely your merit. Thanks again.
Now, the script in the post #3 is fixed and updated.