├── .gitignore ├── Documentation ├── Categories │ ├── NSData+SFPackedBits.html │ ├── NSMutableData+SFAppendValue.html │ └── NSString+SFPascalString.html ├── Classes │ ├── SFPSDBevelEffectLayerInformation.html │ ├── SFPSDDropShadowEffectLayerInformation.html │ ├── SFPSDGroupClosingLayer.html │ ├── SFPSDGroupLayer.html │ ├── SFPSDGroupOpeningLayer.html │ ├── SFPSDInnerGlowEffectLayerInformation.html │ ├── SFPSDInnerShadowEffectLayerInformation.html │ ├── SFPSDLayer.html │ ├── SFPSDOuterGlowEffectLayerInformation.html │ ├── SFPSDSolidFillEffectLayerInformation.html │ └── SFPSDWriter.html ├── css │ ├── styles.css │ └── stylesPrint.css ├── hierarchy.html ├── img │ ├── button_bar_background.png │ ├── disclosure.png │ ├── disclosure_open.png │ ├── library_background.png │ └── title_background.png └── index.html ├── Example Projects ├── SFPSDWriter Mac OS X │ ├── SFPSDWriter Mac OS X.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ └── SFPSDWriter Mac OS X │ │ ├── Resources │ │ ├── firstImage.png │ │ └── secondImage.png │ │ ├── SFAppDelegate.h │ │ ├── SFAppDelegate.m │ │ ├── SFPSDWriter Mac OS X-Info.plist │ │ ├── SFPSDWriter Mac OS X-Prefix.pch │ │ ├── en.lproj │ │ ├── Credits.rtf │ │ ├── InfoPlist.strings │ │ └── MainMenu.xib │ │ └── main.m ├── SFPSDWriter Stress Tester │ ├── SFPSDWriter Stress Tester.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ └── SFPSDWriter Stress Tester │ │ ├── SFAppDelegate.h │ │ ├── SFAppDelegate.m │ │ ├── SFPSDWriter Stress Tester-Info.plist │ │ ├── SFPSDWriter Stress Tester-Prefix.pch │ │ ├── en.lproj │ │ ├── Credits.rtf │ │ ├── InfoPlist.strings │ │ └── MainMenu.xib │ │ ├── layerImage.jpg │ │ ├── layerImageCMYK.jpg │ │ └── main.m └── SFPSDWriter iOS │ ├── SFPSDWriter iOS.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── SFPSDWriter iOS │ ├── Default-568h@2x.png │ ├── Default.png │ ├── Default@2x.png │ ├── Resources │ ├── firstImage.png │ └── secondImage.png │ ├── SFAppDelegate.h │ ├── SFAppDelegate.m │ ├── SFPSDWriter iOS-Info.plist │ ├── SFPSDWriter iOS-Prefix.pch │ ├── SFViewController.h │ ├── SFViewController.m │ ├── en.lproj │ ├── InfoPlist.strings │ ├── MainStoryboard_iPad.storyboard │ └── MainStoryboard_iPhone.storyboard │ └── main.m ├── Framework ├── SFPSDWriter.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── SFPSDWriter │ ├── SFPSDWriter-Info.plist │ ├── SFPSDWriter-Prefix.pch │ └── en.lproj │ └── InfoPlist.strings ├── LICENSE.txt ├── Library └── SFPSDWriter │ ├── Categories │ ├── NSData+SFPackedBits.h │ ├── NSData+SFPackedBits.m │ ├── NSMutableData+SFAppendValue.h │ ├── NSMutableData+SFAppendValue.m │ ├── NSString+SFPascalString.h │ └── NSString+SFPascalString.m │ ├── ICCProfileData │ ├── AdobeRGB1998 │ ├── GenericRGB │ └── sRGB │ ├── Layer Classes │ ├── Constants │ │ ├── SFPSDEffectsLayerEffectSignatures.h │ │ ├── SFPSDEffectsLayerEffectSignatures.m │ │ ├── SFPSDLayerBlendModes.h │ │ └── SFPSDLayerBlendModes.m │ ├── Effect Layer Information Classes │ │ ├── SFPSDBevelEffectLayerInformation.h │ │ ├── SFPSDBevelEffectLayerInformation.m │ │ ├── SFPSDDropShadowEffectLayerInformation.h │ │ ├── SFPSDDropShadowEffectLayerInformation.m │ │ ├── SFPSDEffectLayerInformations.h │ │ ├── SFPSDInnerGlowEffectLayerInformation.h │ │ ├── SFPSDInnerGlowEffectLayerInformation.m │ │ ├── SFPSDInnerShadowEffectLayerInformation.h │ │ ├── SFPSDInnerShadowEffectLayerInformation.m │ │ ├── SFPSDOuterGlowEffectLayerInformation.h │ │ ├── SFPSDOuterGlowEffectLayerInformation.m │ │ ├── SFPSDSolidFillEffectLayerInformation.h │ │ └── SFPSDSolidFillEffectLayerInformation.m │ ├── SFPSDGroupClosingLayer.h │ ├── SFPSDGroupClosingLayer.m │ ├── SFPSDGroupLayer.h │ ├── SFPSDGroupLayer.m │ ├── SFPSDGroupOpeningLayer.h │ ├── SFPSDGroupOpeningLayer.m │ ├── SFPSDLayer.h │ └── SFPSDLayer.m │ ├── SFPSDWriter.h │ └── SFPSDWriter.m ├── README.md └── SFPSDWriter.podspec /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X temporary files that should never be committed 2 | .DS_Store 3 | 4 | # c.f. http://www.westwind.com/reference/os-x/invisibles.html 5 | .Trashes 6 | 7 | # c.f. http://www.westwind.com/reference/os-x/invisibles.html 8 | *.swp 9 | 10 | # For the main ones I use (e.g. Eclipse), it should be excluded 11 | # from source-control, but YMMV 12 | *.lock 13 | 14 | # Xcode temporary files that should never be committed 15 | *~.nib 16 | 17 | # Xcode build files - 18 | DerivedData/ 19 | 20 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build" 21 | build/ 22 | 23 | # Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) 24 | # .pbxuser: http://lists.apple.com/archives/xcode-users/2004/Jan/msg00193.html 25 | *.pbxuser 26 | # .mode1v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html 27 | *.mode1v3 28 | # .mode2v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html 29 | *.mode2v3 30 | # .perspectivev3: http://stackoverflow.com/questions/5223297/xcode-projects-what-is-a-perspectivev3-file 31 | *.perspectivev3 32 | 33 | # NB: also, whitelist the default ones, some projects need to use these 34 | !default.pbxuser 35 | !default.mode1v3 36 | !default.mode2v3 37 | !default.perspectivev3 38 | 39 | # Xcode 4 - semi-personal settings 40 | xcuserdata 41 | 42 | # Xcode 4 - Deprecated classes 43 | *.moved-aside 44 | 45 | #Development folder 46 | /dev/ 47 | 48 | # Xcode 5 VCS data 49 | *.xccheckout 50 | -------------------------------------------------------------------------------- /Documentation/Categories/NSData+SFPackedBits.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSData(SFPackedBits) Category Reference 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |

SFPSDWriter

15 | Shiny Frog 16 |
17 | 18 | 21 | 53 |
54 | 83 |
84 |
85 | 86 | 92 | 97 |
98 | 99 |
100 | 101 | 102 | 103 | 104 |
Declared inNSData+SFPackedBits.h
NSData+SFPackedBits.m
105 | 106 | 107 | 108 | 109 | 110 | 111 |
112 | 113 |

Tasks

114 | 115 | 116 | 117 | 118 | 119 |
    120 |
  • 121 | 122 | – sfPackedBitsDescription 123 |

    Takes packedBits data and prints out a description of the packed contents by 124 | running the decode operation and explaining via NSLog how the data is being 125 | decoded. Useful for checking that packedBits data is correct.

    126 |
    127 | 128 | 129 |
  • 130 | 131 | – sfPackedBitsForRange:skip: 132 |

    A special version of packedBits which will take the data and pack every nth 133 | value.

    134 |
    135 | 136 | 137 |
  • 138 |
139 | 140 |
141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 |
151 | 152 |

Instance Methods

153 | 154 |
155 | 156 |

sfPackedBitsDescription

157 | 158 | 159 | 160 |
161 |

Takes packedBits data and prints out a description of the packed contents by 162 | running the decode operation and explaining via NSLog how the data is being 163 | decoded. Useful for checking that packedBits data is correct.

164 |
165 | 166 | 167 | 168 |
- (NSString *)sfPackedBitsDescription
169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 |
179 |

Discussion

180 |

Takes packedBits data and prints out a description of the packed contents by 181 | running the decode operation and explaining via NSLog how the data is being 182 | decoded. Useful for checking that packedBits data is correct.

183 |
184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 |
192 |

Declared In

193 | NSData+SFPackedBits.h
194 |
195 | 196 | 197 |
198 | 199 |
200 | 201 |

sfPackedBitsForRange:skip:

202 | 203 | 204 | 205 |
206 |

A special version of packedBits which will take the data and pack every nth 207 | value.

208 |
209 | 210 | 211 | 212 |
- (NSData *)sfPackedBitsForRange:(NSRange)range skip:(int)skip
213 | 214 | 215 | 216 |
217 |

Parameters

218 | 219 |
220 |
skip:
221 |

The number of bytes to advance as the data is encoded. Skip = 1 will 222 | encode every byte, skip = 4 will encode every fourth byte, and so on.

223 |
224 | 225 |
226 |
range:
227 |

The range within the data object that should be encoded. Useful 228 | for specifying a non-zero starting offset to get a certain channel encoded.

229 |
230 | 231 |
232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 |
240 |

Discussion

241 |

A special version of packedBits which will take the data and pack every nth 242 | value.

243 | 244 |

This is important for PSDWriter because it’s necessary to encode R, then G, 245 | then B, then A data – so we essentially start at offset 0, skip 4, then do offset 1, 246 | skip 4, etc… to compress the data with very minimal memory footprint.

247 | 248 |

For normal packbits just to skip = 1

249 |
250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 |
258 |

Declared In

259 | NSData+SFPackedBits.h
260 |
261 | 262 | 263 |
264 | 265 |
266 | 267 | 268 |
269 | 275 | 284 |
285 |
286 | 377 | 378 | -------------------------------------------------------------------------------- /Documentation/Categories/NSMutableData+SFAppendValue.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSMutableData(SFAppendValue) Category Reference 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |

SFPSDWriter

15 | Shiny Frog 16 |
17 | 18 | 21 | 55 |
56 | 87 |
88 |
89 | 90 | 96 | 101 |
102 | 103 |
104 | 105 | 106 | 107 | 108 |
Declared inNSMutableData+SFAppendValue.h
NSMutableData+SFAppendValue.m
109 | 110 | 111 | 112 | 113 | 114 | 115 |
116 | 117 |

Tasks

118 | 119 | 120 | 121 | 122 | 123 |
    124 |
  • 125 | 126 | – sfAppendValue:length: 127 |

    Allows you to append a numeric value to an NSMutableData object and pad it to any length.

    128 |
    129 | 130 | 131 |
  • 132 | 133 | – sfAppendUTF8String:length: 134 |

    Allows you to append a NSString to the NSMutableData object.

    135 |
    136 | 137 | 138 |
  • 139 | 140 | – sfAppendCGColorRef:length: 141 |

    Allows you to append a “Native” CGColorRef to the NSMutableData object. 142 | For example it is used in the Effects Layer in the Additional Layer Information to write the 143 | layer effect color

    144 |
    145 | 146 | 147 |
  • 148 |
149 | 150 |
151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 |
161 | 162 |

Instance Methods

163 | 164 |
165 | 166 |

sfAppendCGColorRef:length:

167 | 168 | 169 | 170 |
171 |

Allows you to append a “Native” CGColorRef to the NSMutableData object. 172 | For example it is used in the Effects Layer in the Additional Layer Information to write the 173 | layer effect color

174 |
175 | 176 | 177 | 178 |
- (void)sfAppendCGColorRef:(CGColorRef)color length:(int)length
179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 |
189 |

Discussion

190 |

Allows you to append a “Native” CGColorRef to the NSMutableData object. 191 | For example it is used in the Effects Layer in the Additional Layer Information to write the 192 | layer effect color

193 |
194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 |
202 |

Declared In

203 | NSMutableData+SFAppendValue.h
204 |
205 | 206 | 207 |
208 | 209 |
210 | 211 |

sfAppendUTF8String:length:

212 | 213 | 214 | 215 |
216 |

Allows you to append a NSString to the NSMutableData object.

217 |
218 | 219 | 220 | 221 |
- (void)sfAppendUTF8String:(NSString *)value length:(int)length
222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 |
232 |

Discussion

233 |

Allows you to append a NSString to the NSMutableData object.

234 |
235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 |
243 |

Declared In

244 | NSMutableData+SFAppendValue.h
245 |
246 | 247 | 248 |
249 | 250 |
251 | 252 |

sfAppendValue:length:

253 | 254 | 255 | 256 |
257 |

Allows you to append a numeric value to an NSMutableData object and pad it to any length.

258 |
259 | 260 | 261 | 262 |
- (void)sfAppendValue:(long)value length:(int)length
263 | 264 | 265 | 266 |
267 |

Parameters

268 | 269 |
270 |
length:
271 |

The number of bytes that should be used to store the value. The value will be padded 272 | to length bytes regardless of the number of bytes required to store it.

273 |
274 | 275 |
276 |
value:
277 |

The value to append

278 |
279 | 280 |
281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 |
289 |

Discussion

290 |

Allows you to append a numeric value to an NSMutableData object and pad it to any length.

291 | 292 |

For example, we could say [data appendValue: 2 withLength: 5], and 00002 would be written 293 | into the data object. Very useful for writing to file formats that have header structures 294 | that require a certain number of bytes be used for a certain value. i.e. PSD and TIFF

295 |
296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 |
304 |

Declared In

305 | NSMutableData+SFAppendValue.h
306 |
307 | 308 | 309 |
310 | 311 |
312 | 313 | 314 |
315 | 321 | 330 |
331 |
332 | 423 | 424 | -------------------------------------------------------------------------------- /Documentation/Categories/NSString+SFPascalString.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSString(SFPascalString) Category Reference 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |

SFPSDWriter

15 | Shiny Frog 16 |
17 | 18 | 21 | 55 |
56 | 87 |
88 |
89 | 90 | 96 | 101 |
102 | 103 |
104 | 105 | 106 | 107 | 108 |
Declared inNSString+SFPascalString.h
NSString+SFPascalString.m
109 | 110 | 111 | 112 | 113 | 114 | 115 |
116 | 117 |

Tasks

118 | 119 | 120 | 121 | 122 | 123 | 147 | 148 |
149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 |
159 | 160 |

Instance Methods

161 | 162 |
163 | 164 |

sfPascalStringLengthPaddedTo:

165 | 166 | 167 | 168 |
169 |

The length of the string padded to the multiples of the padding interval.

170 |
171 | 172 | 173 | 174 |
- (int)sfPascalStringLengthPaddedTo:(int)paddingInterval
175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 |
185 |

Discussion

186 |

The length of the string padded to the multiples of the padding interval.

187 |
188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 |
196 |

Declared In

197 | NSString+SFPascalString.h
198 |
199 | 200 | 201 |
202 | 203 |
204 | 205 |

sfPascalStringPaddedTo:

206 | 207 | 208 | 209 |
210 |

Pascal string padded to multiples of the paddind interval using as padding the unicode char 0x00.

211 |
212 | 213 | 214 | 215 |
- (const char *)sfPascalStringPaddedTo:(int)paddingInterval
216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 |
226 |

Discussion

227 |

Pascal string padded to multiples of the paddind interval using as padding the unicode char 0x00.

228 |
229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 |
237 |

Declared In

238 | NSString+SFPascalString.h
239 |
240 | 241 | 242 |
243 | 244 |
245 | 246 |

sfPascalStringPaddedTo:withPaddingString:

247 | 248 | 249 | 250 |
251 |

Pascal string padded to multiples of the paddind interval.

252 |
253 | 254 | 255 | 256 |
- (const char *)sfPascalStringPaddedTo:(int)paddingInterval withPaddingString:(NSString *)paddingString
257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 |
267 |

Discussion

268 |

Pascal string padded to multiples of the paddind interval.

269 |
270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 |
278 |

Declared In

279 | NSString+SFPascalString.h
280 |
281 | 282 | 283 |
284 | 285 |
286 | 287 | 288 |
289 | 295 | 304 |
305 |
306 | 397 | 398 | -------------------------------------------------------------------------------- /Documentation/Classes/SFPSDGroupClosingLayer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SFPSDGroupClosingLayer Class Reference 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |

SFPSDWriter

15 | Shiny Frog 16 |
17 | 18 | 21 | 56 |
57 | 90 |
91 |
92 | 93 | 99 | 104 |
105 | 106 |
107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 |
Inherits fromSFPSDGroupLayer : SFPSDLayer : NSObject
Declared inSFPSDGroupClosingLayer.h
SFPSDGroupClosingLayer.m
115 | 116 | 117 | 118 | 119 | 120 | 121 |
122 | 123 |

Tasks

124 | 125 | 126 | 127 |

Other Methods

128 | 129 |
    130 |
  • 131 | 132 |   groupOpeningLayer 133 |

    If this property is set – the information from the group opening layer will be copied 134 | to the current layer before writing the extra layer information

    135 |
    136 | property 137 | 138 |
  • 139 |
140 | 141 | 142 | 143 |

Other Methods

144 | 145 |
    146 |
  • 147 | 148 | – extraLayerInformation 149 |

    Extra layer information data. Has to be overridden in the extended classes (i.e. in the 150 | PSDGroupOpeningLayer and PSDGroupClosingLayer).

    151 |
    152 | 153 | 154 |
  • 155 |
156 | 157 |
158 | 159 | 160 | 161 | 162 | 163 |
164 | 165 |

Properties

166 | 167 |
168 | 169 |

groupOpeningLayer

170 | 171 | 172 | 173 |
174 |

If this property is set – the information from the group opening layer will be copied 175 | to the current layer before writing the extra layer information

176 |
177 | 178 | 179 | 180 |
@property (nonatomic, strong) SFPSDGroupOpeningLayer *groupOpeningLayer
181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 |
191 |

Discussion

192 |

If this property is set – the information from the group opening layer will be copied 193 | to the current layer before writing the extra layer information

194 |
195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 |
203 |

Declared In

204 | SFPSDGroupClosingLayer.h
205 |
206 | 207 | 208 |
209 | 210 |
211 | 212 | 213 | 214 | 215 | 216 |
217 | 218 |

Instance Methods

219 | 220 |
221 | 222 |

extraLayerInformation

223 | 224 | 225 | 226 |
227 |

Extra layer information data. Has to be overridden in the extended classes (i.e. in the 228 | PSDGroupOpeningLayer and PSDGroupClosingLayer).

229 |
230 | 231 | 232 | 233 |
- (NSData *)extraLayerInformation
234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 |
244 |

Discussion

245 |

Extra layer information data. Has to be overridden in the extended classes (i.e. in the 246 | PSDGroupOpeningLayer and PSDGroupClosingLayer).

247 |
248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 |
256 |

Declared In

257 | SFPSDLayer.h
258 |
259 | 260 | 261 |
262 | 263 |
264 | 265 | 266 |
267 | 273 | 282 |
283 |
284 | 375 | 376 | -------------------------------------------------------------------------------- /Documentation/Classes/SFPSDGroupOpeningLayer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SFPSDGroupOpeningLayer Class Reference 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |

SFPSDWriter

15 | Shiny Frog 16 |
17 | 18 | 21 | 51 |
52 | 79 |
80 |
81 | 82 | 88 | 93 |
94 | 95 |
96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 |
Inherits fromSFPSDGroupLayer : SFPSDLayer : NSObject
Declared inSFPSDGroupOpeningLayer.h
SFPSDGroupOpeningLayer.m
104 | 105 | 106 | 107 | 108 | 109 | 110 |
111 | 112 |

Tasks

113 | 114 | 115 | 116 | 117 | 118 |
    119 |
  • 120 | 121 | – extraLayerInformation 122 |

    Extra layer information data. Has to be overridden in the extended classes (i.e. in the 123 | PSDGroupOpeningLayer and PSDGroupClosingLayer).

    124 |
    125 | 126 | 127 |
  • 128 |
129 | 130 |
131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 |
141 | 142 |

Instance Methods

143 | 144 |
145 | 146 |

extraLayerInformation

147 | 148 | 149 | 150 |
151 |

Extra layer information data. Has to be overridden in the extended classes (i.e. in the 152 | PSDGroupOpeningLayer and PSDGroupClosingLayer).

153 |
154 | 155 | 156 | 157 |
- (NSData *)extraLayerInformation
158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 |
168 |

Discussion

169 |

Extra layer information data. Has to be overridden in the extended classes (i.e. in the 170 | PSDGroupOpeningLayer and PSDGroupClosingLayer).

171 |
172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 |
180 |

Declared In

181 | SFPSDLayer.h
182 |
183 | 184 | 185 |
186 | 187 |
188 | 189 | 190 |
191 | 197 | 206 |
207 |
208 | 299 | 300 | -------------------------------------------------------------------------------- /Documentation/Classes/SFPSDSolidFillEffectLayerInformation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SFPSDSolidFillEffectLayerInformation Class Reference 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |

SFPSDWriter

15 | Shiny Frog 16 |
17 | 18 | 21 | 64 |
65 | 106 |
107 |
108 | 109 | 115 | 120 |
121 | 122 |
123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 |
Inherits fromNSObject
Declared inSFPSDSolidFillEffectLayerInformation.h
SFPSDSolidFillEffectLayerInformation.m
131 | 132 | 133 | 134 | 135 | 136 | 137 |
138 | 139 |

Tasks

140 | 141 | 142 | 143 |

Other Methods

144 | 145 |
    146 |
  • 147 | 148 |   blendMode 149 | 150 | 151 | property 152 | 153 |
  • 154 | 155 |   color 156 | 157 | 158 | property 159 | 160 |
  • 161 | 162 |   opacity 163 | 164 | 165 | property 166 | 167 |
  • 168 | 169 |   enabled 170 | 171 | 172 | property 173 | 174 |
  • 175 | 176 | – opacity255 177 | 178 | 179 | 180 | 181 |
  • 182 |
183 | 184 | 185 | 186 |

Other Methods

187 | 188 |
    189 |
  • 190 | 191 | – init 192 | 193 | 194 | 195 | 196 |
  • 197 |
198 | 199 |
200 | 201 | 202 | 203 | 204 | 205 |
206 | 207 |

Properties

208 | 209 |
210 | 211 |

blendMode

212 | 213 | 214 | 215 |
@property (nonatomic, strong) NSString *blendMode
216 | 217 | 218 |
219 | 220 |
221 | 222 |

color

223 | 224 | 225 | 226 |
@property (nonatomic, assign) CGColorRef color
227 | 228 | 229 |
230 | 231 |
232 | 233 |

enabled

234 | 235 | 236 | 237 |
@property (nonatomic, assign) BOOL enabled
238 | 239 | 240 |
241 | 242 |
243 | 244 |

opacity

245 | 246 | 247 | 248 |
@property (nonatomic, assign) long opacity
249 | 250 | 251 |
252 | 253 |
254 | 255 | 256 | 257 | 258 | 259 |
260 | 261 |

Instance Methods

262 | 263 |
264 | 265 |

init

266 | 267 | 268 | 269 |
- (id)init
270 | 271 | 272 |
273 | 274 |
275 | 276 |

opacity255

277 | 278 | 279 | 280 |
- (long)opacity255
281 | 282 | 283 |
284 | 285 |
286 | 287 | 288 |
289 | 295 | 304 |
305 |
306 | 397 | 398 | -------------------------------------------------------------------------------- /Documentation/css/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; 3 | font-size: 13px; 4 | } 5 | 6 | code { 7 | font-family: Courier, Consolas, monospace; 8 | font-size: 13px; 9 | color: #666; 10 | } 11 | 12 | pre { 13 | font-family: Courier, Consolas, monospace; 14 | font-size: 13px; 15 | line-height: 18px; 16 | tab-interval: 0.5em; 17 | border: 1px solid #C7CFD5; 18 | background-color: #F1F5F9; 19 | color: #666; 20 | padding: 0.3em 1em; 21 | } 22 | 23 | ul { 24 | list-style-type: square; 25 | } 26 | 27 | li { 28 | margin-bottom: 10px; 29 | } 30 | 31 | a, a code { 32 | text-decoration: none; 33 | color: #36C; 34 | } 35 | 36 | a:hover, a:hover code { 37 | text-decoration: underline; 38 | color: #36C; 39 | } 40 | 41 | h2 { 42 | border-bottom: 1px solid #8391A8; 43 | color: #3C4C6C; 44 | font-size: 187%; 45 | font-weight: normal; 46 | margin-top: 1.75em; 47 | padding-bottom: 2px; 48 | } 49 | 50 | table { 51 | margin-bottom: 4em; 52 | border-collapse:collapse; 53 | vertical-align: middle; 54 | } 55 | 56 | td { 57 | border: 1px solid #9BB3CD; 58 | padding: .667em; 59 | font-size: 100%; 60 | } 61 | 62 | th { 63 | border: 1px solid #9BB3CD; 64 | padding: .3em .667em .3em .667em; 65 | background: #93A5BB; 66 | font-size: 103%; 67 | font-weight: bold; 68 | color: white; 69 | text-align: left; 70 | } 71 | 72 | /* @group Common page elements */ 73 | 74 | #top_header { 75 | height: 91px; 76 | left: 0; 77 | min-width: 598px; 78 | position: absolute; 79 | right: 0; 80 | top: 0; 81 | z-index: 900; 82 | } 83 | 84 | #footer { 85 | clear: both; 86 | padding-top: 20px; 87 | text-align: center; 88 | } 89 | 90 | #contents, #overview_contents { 91 | -webkit-overflow-scrolling: touch; 92 | border-top: 1px solid #2B334F; 93 | position: absolute; 94 | top: 91px; 95 | left: 0; 96 | right: 0; 97 | bottom: 0; 98 | overflow-x: hidden; 99 | overflow-y: auto; 100 | padding-left: 2em; 101 | padding-right: 2em; 102 | padding-top: 1em; 103 | min-width: 550px; 104 | } 105 | 106 | #contents.isShowingTOC { 107 | left: 230px; 108 | min-width: 320px; 109 | } 110 | 111 | .copyright { 112 | font-size: 12px; 113 | } 114 | 115 | .generator { 116 | font-size: 11px; 117 | } 118 | 119 | .main-navigation ul li { 120 | display: inline; 121 | margin-left: 15px; 122 | list-style: none; 123 | } 124 | 125 | .navigation-top { 126 | clear: both; 127 | float: right; 128 | } 129 | 130 | .navigation-bottom { 131 | clear: both; 132 | float: right; 133 | margin-top: 20px; 134 | margin-bottom: -10px; 135 | } 136 | 137 | .open > .disclosure { 138 | background-image: url("../img/disclosure_open.png"); 139 | } 140 | 141 | .disclosure { 142 | background: url("../img/disclosure.png") no-repeat scroll 0 0; 143 | } 144 | 145 | .disclosure, .nodisclosure { 146 | display: inline-block; 147 | height: 8px; 148 | margin-right: 5px; 149 | position: relative; 150 | width: 9px; 151 | } 152 | 153 | /* @end */ 154 | 155 | /* @group Header */ 156 | 157 | #top_header #library { 158 | background: url("../img/library_background.png") repeat-x 0 0 #485E78; 159 | background-color: #ccc; 160 | height: 35px; 161 | font-size: 115%; 162 | } 163 | 164 | #top_header #library #libraryTitle { 165 | color: #FFFFFF; 166 | margin-left: 15px; 167 | text-shadow: 0 -1px 0 #485E78; 168 | top: 8px; 169 | position: absolute; 170 | } 171 | 172 | #libraryTitle { 173 | left: 0; 174 | } 175 | 176 | #top_header #library #developerHome { 177 | color: #92979E; 178 | right: 15px; 179 | top: 8px; 180 | position: absolute; 181 | } 182 | 183 | #top_header #library a:hover { 184 | text-decoration: none; 185 | } 186 | 187 | #top_header #title { 188 | background: url("../img/title_background.png") repeat-x 0 0 #8A98A9; 189 | border-bottom: 1px solid #B6B6B6; 190 | height: 25px; 191 | overflow: hidden; 192 | } 193 | 194 | #top_header h1 { 195 | font-size: 115%; 196 | font-weight: normal; 197 | margin: 0; 198 | padding: 3px 0 2px; 199 | text-align: center; 200 | text-shadow: 0 1px 0 #D5D5D5; 201 | white-space: nowrap; 202 | } 203 | 204 | #headerButtons { 205 | background-color: #D8D8D8; 206 | background-image: url("../img/button_bar_background.png"); 207 | border-bottom: 1px solid #EDEDED; 208 | border-top: 1px solid #2B334F; 209 | font-size: 8pt; 210 | height: 28px; 211 | left: 0; 212 | list-style: none outside none; 213 | margin: 0; 214 | overflow: hidden; 215 | padding: 0; 216 | position: absolute; 217 | right: 0; 218 | top: 61px; 219 | } 220 | 221 | #headerButtons li { 222 | background-repeat: no-repeat; 223 | display: inline; 224 | margin-top: 0; 225 | margin-bottom: 0; 226 | padding: 0; 227 | } 228 | 229 | #toc_button button { 230 | border-color: #ACACAC; 231 | border-style: none solid none none; 232 | border-width: 0 1px 0 0; 233 | height: 28px; 234 | margin: 0; 235 | padding-left: 30px; 236 | text-align: left; 237 | width: 230px; 238 | } 239 | 240 | li#jumpto_button { 241 | left: 230px; 242 | margin-left: 0; 243 | position: absolute; 244 | } 245 | 246 | li#jumpto_button select { 247 | height: 22px; 248 | margin: 5px 2px 0 10px; 249 | max-width: 300px; 250 | } 251 | 252 | /* @end */ 253 | 254 | /* @group Table of contents */ 255 | 256 | #tocContainer.isShowingTOC { 257 | border-right: 1px solid #ACACAC; 258 | display: block; 259 | overflow-x: hidden; 260 | overflow-y: auto; 261 | padding: 0; 262 | } 263 | 264 | #tocContainer { 265 | background-color: #E4EBF7; 266 | border-top: 1px solid #2B334F; 267 | bottom: 0; 268 | display: none; 269 | left: 0; 270 | overflow: hidden; 271 | position: absolute; 272 | top: 91px; 273 | width: 229px; 274 | } 275 | 276 | #tocContainer > ul#toc { 277 | font-size: 11px; 278 | margin: 0; 279 | padding: 12px 0 18px; 280 | width: 209px; 281 | -moz-user-select: none; 282 | -webkit-user-select: none; 283 | user-select: none; 284 | } 285 | 286 | #tocContainer > ul#toc > li { 287 | margin: 0; 288 | padding: 0 0 7px 30px; 289 | text-indent: -15px; 290 | } 291 | 292 | #tocContainer > ul#toc > li > .sectionName a { 293 | color: #000000; 294 | font-weight: bold; 295 | } 296 | 297 | #tocContainer > ul#toc > li > .sectionName a:hover { 298 | text-decoration: none; 299 | } 300 | 301 | #tocContainer > ul#toc li.children > ul { 302 | display: none; 303 | height: 0; 304 | } 305 | 306 | #tocContainer > ul#toc > li > ul { 307 | margin: 0; 308 | padding: 0; 309 | } 310 | 311 | #tocContainer > ul#toc > li > ul, ul#toc > li > ul > li { 312 | margin-left: 0; 313 | margin-bottom: 0; 314 | padding-left: 15px; 315 | } 316 | 317 | #tocContainer > ul#toc > li ul { 318 | list-style: none; 319 | margin-right: 0; 320 | padding-right: 0; 321 | } 322 | 323 | #tocContainer > ul#toc li.children.open > ul { 324 | display: block; 325 | height: auto; 326 | margin-left: -15px; 327 | padding-left: 0; 328 | } 329 | 330 | #tocContainer > ul#toc > li > ul, ul#toc > li > ul > li { 331 | margin-left: 0; 332 | padding-left: 15px; 333 | } 334 | 335 | #tocContainer li ul li { 336 | margin-top: 0.583em; 337 | overflow: hidden; 338 | text-overflow: ellipsis; 339 | white-space: nowrap; 340 | } 341 | 342 | #tocContainer li ul li span.sectionName { 343 | white-space: normal; 344 | } 345 | 346 | #tocContainer > ul#toc > li > ul > li > .sectionName a { 347 | font-weight: bold; 348 | } 349 | 350 | #tocContainer > ul#toc > li > ul a { 351 | color: #4F4F4F; 352 | } 353 | 354 | /* @end */ 355 | 356 | /* @group Index formatting */ 357 | 358 | .index-title { 359 | font-size: 13px; 360 | font-weight: normal; 361 | } 362 | 363 | .index-column { 364 | float: left; 365 | width: 30%; 366 | min-width: 200px; 367 | font-size: 11px; 368 | } 369 | 370 | .index-column ul { 371 | margin: 8px 0 0 0; 372 | padding: 0; 373 | list-style: none; 374 | } 375 | 376 | .index-column ul li { 377 | margin: 0 0 3px 0; 378 | padding: 0; 379 | } 380 | 381 | .hierarchy-column { 382 | min-width: 400px; 383 | } 384 | 385 | .hierarchy-column ul { 386 | margin: 3px 0 0 15px; 387 | } 388 | 389 | .hierarchy-column ul li { 390 | list-style-type: square; 391 | } 392 | 393 | /* @end */ 394 | 395 | /* @group Common formatting elements */ 396 | 397 | .title { 398 | font-weight: normal; 399 | font-size: 215%; 400 | margin-top:0; 401 | } 402 | 403 | .subtitle { 404 | font-weight: normal; 405 | font-size: 180%; 406 | color: #3C4C6C; 407 | border-bottom: 1px solid #5088C5; 408 | } 409 | 410 | .subsubtitle { 411 | font-weight: normal; 412 | font-size: 145%; 413 | height: 0.7em; 414 | } 415 | 416 | .note { 417 | border: 1px solid #5088C5; 418 | background-color: white; 419 | margin: 1.667em 0 1.75em 0; 420 | padding: 0 .667em .083em .750em; 421 | } 422 | 423 | .warning { 424 | border: 1px solid #5088C5; 425 | background-color: #F0F3F7; 426 | margin-bottom: 0.5em; 427 | padding: 0.3em 0.8em; 428 | } 429 | 430 | .bug { 431 | border: 1px solid #000; 432 | background-color: #ffffcc; 433 | margin-bottom: 0.5em; 434 | padding: 0.3em 0.8em; 435 | } 436 | 437 | .deprecated { 438 | color: #F60425; 439 | } 440 | 441 | /* @end */ 442 | 443 | /* @group Common layout */ 444 | 445 | .section { 446 | margin-top: 3em; 447 | } 448 | 449 | /* @end */ 450 | 451 | /* @group Object specification section */ 452 | 453 | .section-specification { 454 | margin-left: 2.5em; 455 | margin-right: 2.5em; 456 | font-size: 12px; 457 | } 458 | 459 | .section-specification table { 460 | margin-bottom: 0em; 461 | border-top: 1px solid #d6e0e5; 462 | } 463 | 464 | .section-specification td { 465 | vertical-align: top; 466 | border-bottom: 1px solid #d6e0e5; 467 | border-left-width: 0px; 468 | border-right-width: 0px; 469 | border-top-width: 0px; 470 | padding: .6em; 471 | } 472 | 473 | .section-specification .specification-title { 474 | font-weight: bold; 475 | } 476 | 477 | /* @end */ 478 | 479 | /* @group Tasks section */ 480 | 481 | .task-list { 482 | list-style-type: none; 483 | padding-left: 0px; 484 | } 485 | 486 | .task-list li { 487 | margin-bottom: 3px; 488 | } 489 | 490 | .task-item-suffix { 491 | color: #996; 492 | font-size: 12px; 493 | font-style: italic; 494 | margin-left: 0.5em; 495 | } 496 | 497 | span.tooltip span.tooltip { 498 | font-size: 1.0em; 499 | display: none; 500 | padding: 0.3em; 501 | border: 1px solid #aaa; 502 | background-color: #fdfec8; 503 | color: #000; 504 | text-align: left; 505 | } 506 | 507 | span.tooltip:hover span.tooltip { 508 | display: block; 509 | position: absolute; 510 | margin-left: 2em; 511 | } 512 | 513 | /* @end */ 514 | 515 | /* @group Method section */ 516 | 517 | .section-method { 518 | margin-top: 2.3em; 519 | } 520 | 521 | .method-title { 522 | margin-bottom: 1.5em; 523 | } 524 | 525 | .method-subtitle { 526 | margin-top: 0.7em; 527 | margin-bottom: 0.2em; 528 | } 529 | 530 | .method-subsection p { 531 | margin-top: 0.4em; 532 | margin-bottom: 0.8em; 533 | } 534 | 535 | .method-declaration { 536 | margin-top:1.182em; 537 | margin-bottom:.909em; 538 | } 539 | 540 | .method-declaration code { 541 | font:14px Courier, Consolas, monospace; 542 | color:#000; 543 | } 544 | 545 | .declaration { 546 | color: #000; 547 | } 548 | 549 | .argument-def { 550 | margin-top: 0.3em; 551 | margin-bottom: 0.3em; 552 | } 553 | 554 | .argument-def dd { 555 | margin-left: 1.25em; 556 | } 557 | 558 | .see-also-section ul { 559 | list-style-type: none; 560 | padding-left: 0px; 561 | margin-top: 0; 562 | } 563 | 564 | .see-also-section li { 565 | margin-bottom: 3px; 566 | } 567 | 568 | .declared-in-ref { 569 | color: #666; 570 | } 571 | 572 | #tocContainer.hideInXcode { 573 | display: none; 574 | border: 0px solid black; 575 | } 576 | 577 | #top_header.hideInXcode { 578 | display: none; 579 | } 580 | 581 | #contents.hideInXcode { 582 | border: 0px solid black; 583 | top: 0px; 584 | left: 0px; 585 | } 586 | 587 | /* @end */ 588 | 589 | -------------------------------------------------------------------------------- /Documentation/css/stylesPrint.css: -------------------------------------------------------------------------------- 1 | 2 | header { 3 | display: none; 4 | } 5 | 6 | div.main-navigation, div.navigation-top { 7 | display: none; 8 | } 9 | 10 | div#overview_contents, div#contents.isShowingTOC, div#contents { 11 | overflow: visible; 12 | position: relative; 13 | top: 0px; 14 | border: none; 15 | left: 0; 16 | } 17 | #tocContainer.isShowingTOC { 18 | display: none; 19 | } 20 | nav { 21 | display: none; 22 | } -------------------------------------------------------------------------------- /Documentation/hierarchy.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SFPSDWriter Hierarchy 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |

SFPSDWriter

14 | Shiny Frog 15 |
16 | 17 | 20 | 21 |
22 |
23 |
24 | 27 | 32 |
33 | 34 |
35 |

Class Hierarchy

36 | 37 | 76 | 77 |
78 | 79 | 80 | 81 |
82 | 83 | 84 |

Category References

85 | 94 | 95 |
96 | 97 |
98 | 101 | 111 |
112 |
113 | 114 | -------------------------------------------------------------------------------- /Documentation/img/button_bar_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Documentation/img/button_bar_background.png -------------------------------------------------------------------------------- /Documentation/img/disclosure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Documentation/img/disclosure.png -------------------------------------------------------------------------------- /Documentation/img/disclosure_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Documentation/img/disclosure_open.png -------------------------------------------------------------------------------- /Documentation/img/library_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Documentation/img/library_background.png -------------------------------------------------------------------------------- /Documentation/img/title_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Documentation/img/title_background.png -------------------------------------------------------------------------------- /Documentation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SFPSDWriter Reference 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |

SFPSDWriter

14 | Shiny Frog 15 |
16 | 17 | 20 | 21 |
22 |
23 |
24 | 27 | 32 |
33 | 34 | 35 | 36 | 37 | 38 | 66 | 67 | 68 | 69 |
70 | 71 | 72 |

Category References

73 | 82 | 83 |
84 | 85 |
86 | 89 | 99 |
100 |
101 | 102 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Mac OS X/SFPSDWriter Mac OS X.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Mac OS X/SFPSDWriter Mac OS X/Resources/firstImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Example Projects/SFPSDWriter Mac OS X/SFPSDWriter Mac OS X/Resources/firstImage.png -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Mac OS X/SFPSDWriter Mac OS X/Resources/secondImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Example Projects/SFPSDWriter Mac OS X/SFPSDWriter Mac OS X/Resources/secondImage.png -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Mac OS X/SFPSDWriter Mac OS X/SFAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFAppDelegate.h 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 12/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SFAppDelegate : NSObject 12 | 13 | @property (assign) IBOutlet NSWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Mac OS X/SFPSDWriter Mac OS X/SFAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SFAppDelegate.m 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 12/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import "SFAppDelegate.h" 10 | 11 | #import "SFPSDWriter.h" 12 | 13 | @implementation SFAppDelegate 14 | 15 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification 16 | { 17 | // The images we want to insert in the PSD 18 | NSImage *firstImage = [NSImage imageNamed:@"firstImage"]; 19 | NSImage *secondImage = [NSImage imageNamed:@"secondImage"]; 20 | 21 | // SFPSDWriter instance 22 | SFPSDWriter *psdWriter = [[SFPSDWriter alloc] initWithDocumentSize:NSSizeToCGSize(firstImage.size) andResolution:300.0 andResolutionUnit:SFPSDResolutionUnitPPI]; 23 | 24 | // We want all our layers to be included in a group... 25 | SFPSDGroupOpeningLayer *firstGroup = [psdWriter openGroupLayerWithName:@"We ♥ groups!"]; 26 | 27 | // ... and the group should be open at file opening 28 | [firstGroup setIsOpened:YES]; 29 | 30 | // Adding the first image layer 31 | [psdWriter addLayerWithCGImage:[[[firstImage representations] objectAtIndex:0] CGImage] 32 | andName:@"First Layer" 33 | andOpacity:1 34 | andOffset:NSMakePoint(0, 0)]; 35 | 36 | // I mean, we really love groups 37 | // This time we don't need to change group's attributes so we don't store the reference 38 | [psdWriter openGroupLayerWithName:@"You'll have to open me!"]; 39 | 40 | // The second image will be in the second group, offsetted by (116px, 66px), semi-transparent... 41 | SFPSDLayer *secondLayer = [psdWriter addLayerWithCGImage:[[[secondImage representations] objectAtIndex:0] CGImage] 42 | andName:@"Second Layer" 43 | andOpacity:0.5 44 | andOffset:NSMakePoint(116, 66)]; 45 | 46 | // ... and with "Darken" blend mode 47 | [secondLayer setBlendMode:SFPSDLayerBlendModeDarken]; 48 | 49 | // We'll prepare the Drop Shadow Effect Layer information 50 | SFPSDDropShadowEffectLayerInformation *dropShadowInformation = [[SFPSDDropShadowEffectLayerInformation alloc] init]; 51 | dropShadowInformation.enabled = YES; 52 | dropShadowInformation.size = 100; 53 | dropShadowInformation.angle = 90; 54 | dropShadowInformation.distance = 5; 55 | dropShadowInformation.color = [[NSColor redColor] CGColor]; 56 | dropShadowInformation.blendMode = SFPSDLayerBlendModeNormal; 57 | dropShadowInformation.useGlobalLight = NO; 58 | dropShadowInformation.opacity = 100; 59 | 60 | // We'll set the Drop Sahdow on the second layer (we can add it to the SFPSDGroupOpeningLayer too) 61 | [secondLayer setDropShadowEffectLayerInformation:dropShadowInformation]; 62 | 63 | // Other available Effect Layers are: 64 | // - Inner Shadow (SFPSDInnerShadowEffectLayerInformation) 65 | // - Outer Glow (SFPSDOuterGlowEffectLayerInformation) 66 | // - Inner Glow (SFPSDInnerGlowEffectLayerInformation) 67 | // - Bevel (SFPSDBevelEffectLayerInformation) 68 | // - Solid Fill (SFPSDSolidFillEffectLayerInformation) 69 | 70 | // We have to close every group we've opened 71 | [psdWriter closeCurrentGroupLayer]; // second group 72 | [psdWriter closeCurrentGroupLayer]; // first group 73 | 74 | // We can change the embedded color profile of the document (for example with an "sRGB IEC61966-2.1") 75 | [psdWriter setColorProfile:SFPSDSRGBColorProfile]; 76 | 77 | // We'll write our test file to the Desktop 78 | NSString *basePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Desktop"]; 79 | NSString *fullFilePath = [basePath stringByAppendingPathComponent:@"SFPSDWriter Test File.psd"]; 80 | 81 | // Retrieving the PSD data 82 | NSError *error = nil; 83 | NSData *psd = [psdWriter createPSDDataWithError:&error]; 84 | 85 | // Checking for errors 86 | if (nil != error) { 87 | NSLog(@"There was an error writing the PSD: %@", [error description]); 88 | return; 89 | } 90 | 91 | // Writing the data on disk 92 | [psd writeToFile:fullFilePath atomically:NO]; 93 | 94 | // Opening the newly created file! :) 95 | [[NSWorkspace sharedWorkspace] openFile:fullFilePath]; 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Mac OS X/SFPSDWriter Mac OS X/SFPSDWriter Mac OS X-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | net.shinyfrog.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSHumanReadableCopyright 28 | Copyright © 2013 Shiny Frog. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Mac OS X/SFPSDWriter Mac OS X/SFPSDWriter Mac OS X-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'SFPSDWriter Mac OS X' target in the 'SFPSDWriter Mac OS X' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Mac OS X/SFPSDWriter Mac OS X/en.lproj/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;} 2 | {\colortbl;\red255\green255\blue255;} 3 | \paperw9840\paperh8400 4 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 5 | 6 | \f0\b\fs24 \cf0 Engineering: 7 | \b0 \ 8 | Some people\ 9 | \ 10 | 11 | \b Human Interface Design: 12 | \b0 \ 13 | Some other people\ 14 | \ 15 | 16 | \b Testing: 17 | \b0 \ 18 | Hopefully not nobody\ 19 | \ 20 | 21 | \b Documentation: 22 | \b0 \ 23 | Whoever\ 24 | \ 25 | 26 | \b With special thanks to: 27 | \b0 \ 28 | Mom\ 29 | } 30 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Mac OS X/SFPSDWriter Mac OS X/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Mac OS X/SFPSDWriter Mac OS X/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 12/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **)argv); 14 | } 15 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Stress Tester/SFPSDWriter Stress Tester.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Stress Tester/SFPSDWriter Stress Tester/SFAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFAppDelegate.h 3 | // SFPSDWriterStressTest 4 | // 5 | // Created by Konstantin Erokhin on 13/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SFPSDWriter.h" 12 | 13 | @interface SFAppDelegate : NSObject 14 | 15 | @property (assign) IBOutlet NSWindow *window; 16 | @property (strong) SFPSDWriter *writer; 17 | 18 | - (IBAction)addLayer:(id)sender; 19 | - (IBAction)writePSD:(id)sender; 20 | - (IBAction)clearPSDWriter:(id)sender; 21 | 22 | - (IBAction)add10Layers:(id)sender; 23 | - (IBAction)add100Layers:(id)sender; 24 | - (IBAction)writePSD10Times:(id)sender; 25 | - (IBAction)changeImageSize:(id)sender; 26 | 27 | - (IBAction)openGroupLayer:(id)sender; 28 | - (IBAction)closeGroupLayer:(id)sender; 29 | 30 | - (IBAction)addTopEscapingLayer:(id)sender; 31 | - (IBAction)addBottomEscapingLayer:(id)sender; 32 | - (IBAction)addLeftEscapingLayer:(id)sender; 33 | - (IBAction)addRightEscapingLayer:(id)sender; 34 | 35 | - (IBAction)addAllEscapingLayers:(id)sender; 36 | @end 37 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Stress Tester/SFPSDWriter Stress Tester/SFAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SFAppDelegate.m 3 | // SFPSDWriterStressTest 4 | // 5 | // Created by Konstantin Erokhin on 13/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #include 10 | 11 | #import "SFAppDelegate.h" 12 | 13 | #import "NSData+SFPackedBits.h" 14 | 15 | @implementation SFAppDelegate 16 | 17 | @synthesize writer = _writer; 18 | 19 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification 20 | { 21 | // Insert code here to initialize your application 22 | self.writer = [[SFPSDWriter alloc] initWithDocumentSize:CGSizeMake(1000, 1000) andResolution:300.0 andResolutionUnit:SFPSDResolutionUnitPPI andHasTransparentLayers:YES andLayers:nil]; 23 | } 24 | 25 | - (void)addLayerWithOffset:(CGPoint)offset andOpacity:(float)opacity 26 | { 27 | CGImageRef image = [[[[NSImage imageNamed:@"layerImage"] representations] objectAtIndex:0] CGImage]; 28 | // CGImageRef imageCMYK = [[[[NSImage imageNamed:@"layerImageCMYK"] representations] objectAtIndex:0] CGImage]; 29 | 30 | NSString *name = [NSString stringWithFormat:@"random layer %ld", (unsigned long)([self.writer.layers count] + 1)]; 31 | 32 | [self.writer addLayerWithCGImage:image andName:name andOpacity:opacity andOffset:offset]; 33 | // [self.writer addLayerWithCGImage:imageCMYK andName:name andOpacity:opacity andOffset:offset]; 34 | 35 | } 36 | 37 | - (IBAction)addLayer:(id)sender { 38 | int wOffsetR = arc4random() % 740; 39 | int hOffsetR = arc4random() % 790; 40 | 41 | CGPoint offset = CGPointMake(wOffsetR, hOffsetR); 42 | 43 | int opacityR = arc4random() % 100; 44 | 45 | float opacity = (float)opacityR / 100; 46 | 47 | [self addLayerWithOffset:offset andOpacity:opacity]; 48 | } 49 | 50 | - (IBAction)writePSD:(id)sender { 51 | // We'll write our test file to the Desktop 52 | NSString *basePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Desktop"]; 53 | NSString *fullFilePath = [basePath stringByAppendingPathComponent:@"SFPSDWriter Test File.psd"]; 54 | 55 | // Retrieving the PSD data 56 | NSError *error = nil; 57 | NSData *psd = [self.writer createPSDDataWithError:&error]; 58 | 59 | if (nil != error) { 60 | NSLog(@"ERROR? ERROR: %@", [error description]); 61 | } 62 | 63 | // Writing the data on disk 64 | [psd writeToFile:fullFilePath atomically:NO]; 65 | } 66 | 67 | - (IBAction)clearPSDWriter:(id)sender { 68 | [self setWriter:nil]; 69 | self.writer = [[SFPSDWriter alloc] initWithDocumentSize:CGSizeMake(1000, 1000)]; 70 | } 71 | 72 | - (IBAction)add10Layers:(id)sender { 73 | for (int i = 0; i < 10; i++) { 74 | [self addLayer:nil]; 75 | } 76 | } 77 | 78 | - (IBAction)add100Layers:(id)sender { 79 | for (int i = 0; i < 10; i++) { 80 | [self add10Layers:nil]; 81 | } 82 | } 83 | 84 | - (IBAction)writePSD10Times:(id)sender { 85 | for (int i = 0; i < 10; i++) { 86 | [self writePSD:nil]; 87 | } 88 | } 89 | 90 | - (IBAction)changeImageSize:(id)sender { 91 | CGSize currentSize = [self.writer documentSize]; 92 | currentSize.width = currentSize.width - 100; 93 | currentSize.height = currentSize.height - 100; 94 | [self.writer setDocumentSize:currentSize]; 95 | } 96 | 97 | - (IBAction)openGroupLayer:(id)sender { 98 | NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 99 | NSMutableString *randomString = [NSMutableString stringWithCapacity:10]; 100 | for (int i=0; i < 10; i++) { 101 | [randomString appendFormat: @"%C", [letters characterAtIndex: arc4random() % [letters length]]]; 102 | } 103 | [self.writer openGroupLayerWithName:randomString andOpacity:1.0 andIsOpened:YES]; 104 | } 105 | 106 | - (IBAction)closeGroupLayer:(id)sender { 107 | NSError *error = nil; 108 | [self.writer closeCurrentGroupLayerWithError:&error]; 109 | 110 | if (nil != error) { 111 | NSLog(@"Error in closing group layer: %@", [error debugDescription]); 112 | } 113 | } 114 | 115 | - (IBAction)addTopEscapingLayer:(id)sender 116 | { 117 | [self addLayerWithOffset:CGPointMake(1000/2 - 250/2, -100) andOpacity:1.0]; 118 | } 119 | 120 | - (IBAction)addBottomEscapingLayer:(id)sender 121 | { 122 | [self addLayerWithOffset:CGPointMake(1000/2 - 250/2, 900) andOpacity:1.0]; 123 | } 124 | 125 | - (IBAction)addLeftEscapingLayer:(id)sender 126 | { 127 | [self addLayerWithOffset:CGPointMake(-100, 1000/2 - 200/2) andOpacity:1.0]; 128 | } 129 | 130 | - (IBAction)addRightEscapingLayer:(id)sender 131 | { 132 | [self addLayerWithOffset:CGPointMake(900, 1000/2 - 200/2) andOpacity:1.0]; 133 | } 134 | 135 | - (IBAction)addAllEscapingLayers:(id)sender 136 | { 137 | [self addTopEscapingLayer:nil]; 138 | [self addBottomEscapingLayer:nil]; 139 | [self addLeftEscapingLayer:nil]; 140 | [self addRightEscapingLayer:nil]; 141 | } 142 | 143 | @end 144 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Stress Tester/SFPSDWriter Stress Tester/SFPSDWriter Stress Tester-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | net.shinyfrog.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSHumanReadableCopyright 28 | Copyright © 2013 Shiny Frog. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Stress Tester/SFPSDWriter Stress Tester/SFPSDWriter Stress Tester-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'SFPSDWriter Stress Tester' target in the 'SFPSDWriter Stress Tester' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Stress Tester/SFPSDWriter Stress Tester/en.lproj/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;} 2 | {\colortbl;\red255\green255\blue255;} 3 | \paperw9840\paperh8400 4 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 5 | 6 | \f0\b\fs24 \cf0 Engineering: 7 | \b0 \ 8 | Some people\ 9 | \ 10 | 11 | \b Human Interface Design: 12 | \b0 \ 13 | Some other people\ 14 | \ 15 | 16 | \b Testing: 17 | \b0 \ 18 | Hopefully not nobody\ 19 | \ 20 | 21 | \b Documentation: 22 | \b0 \ 23 | Whoever\ 24 | \ 25 | 26 | \b With special thanks to: 27 | \b0 \ 28 | Mom\ 29 | } 30 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Stress Tester/SFPSDWriter Stress Tester/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Stress Tester/SFPSDWriter Stress Tester/layerImage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Example Projects/SFPSDWriter Stress Tester/SFPSDWriter Stress Tester/layerImage.jpg -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Stress Tester/SFPSDWriter Stress Tester/layerImageCMYK.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Example Projects/SFPSDWriter Stress Tester/SFPSDWriter Stress Tester/layerImageCMYK.jpg -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter Stress Tester/SFPSDWriter Stress Tester/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SFPSDWriter Stress Tester 4 | // 5 | // Created by Konstantin Erokhin on 17/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **)argv); 14 | } 15 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter iOS/SFPSDWriter iOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/Default-568h@2x.png -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/Default.png -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/Default@2x.png -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/Resources/firstImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/Resources/firstImage.png -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/Resources/secondImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/Resources/secondImage.png -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/SFAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFAppDelegate.h 3 | // SFPSDWriter iOS 4 | // 5 | // Created by Konstantin Erokhin on 11/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SFAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/SFAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SFAppDelegate.m 3 | // SFPSDWriter iOS 4 | // 5 | // Created by Konstantin Erokhin on 11/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import "SFAppDelegate.h" 10 | 11 | #import "SFPSDWriter.h" 12 | 13 | @implementation SFAppDelegate 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 16 | { 17 | // Override point for customization after application launch. 18 | return YES; 19 | } 20 | 21 | - (void)applicationWillResignActive:(UIApplication *)application 22 | { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | - (void)applicationDidEnterBackground:(UIApplication *)application 28 | { 29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application 34 | { 35 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 36 | } 37 | 38 | - (void)applicationDidBecomeActive:(UIApplication *)application 39 | { 40 | // The images we want to insert in the PSD 41 | UIImage *firstImage = [UIImage imageNamed:@"firstImage"]; 42 | UIImage *secondImage = [UIImage imageNamed:@"secondImage"]; 43 | 44 | // SFPSDWriter instance 45 | SFPSDWriter *psdWriter = [[SFPSDWriter alloc] initWithDocumentSize:firstImage.size andResolution:300.0 andResolutionUnit:SFPSDResolutionUnitPPI]; 46 | 47 | // We want all our layers to be included in a group... 48 | SFPSDGroupOpeningLayer *firstGroup = [psdWriter openGroupLayerWithName:@"We ♥ groups!"]; 49 | 50 | // ... and the group should be open at file opening 51 | [firstGroup setIsOpened:YES]; 52 | 53 | // Adding the first image layer 54 | [psdWriter addLayerWithCGImage:[firstImage CGImage] 55 | andName:@"First Layer" 56 | andOpacity:1 57 | andOffset:CGPointMake(0, 0)]; 58 | 59 | // I mean, we really love groups 60 | // This time we don't need to change group's attributes so we don't store the reference 61 | [psdWriter openGroupLayerWithName:@"You'll have to open me!"]; 62 | 63 | // The second image will be in the second group, offsetted by (116px, 66px), semi-transparent... 64 | SFPSDLayer *secondLayer = [psdWriter addLayerWithCGImage:[secondImage CGImage] 65 | andName:@"Second Layer" 66 | andOpacity:0.5 67 | andOffset:CGPointMake(116, 66)]; 68 | 69 | // ... and with "Darken" blend mode 70 | [secondLayer setBlendMode:SFPSDLayerBlendModeDarken]; 71 | 72 | // We'll prepare the Drop Shadow Effect Layer information 73 | SFPSDDropShadowEffectLayerInformation *dropShadowInformation = [[SFPSDDropShadowEffectLayerInformation alloc] init]; 74 | dropShadowInformation.enabled = YES; 75 | dropShadowInformation.size = 100; 76 | dropShadowInformation.angle = 90; 77 | dropShadowInformation.distance = 5; 78 | dropShadowInformation.color = [[UIColor redColor] CGColor]; 79 | dropShadowInformation.blendMode = SFPSDLayerBlendModeNormal; 80 | dropShadowInformation.useGlobalLight = NO; 81 | dropShadowInformation.opacity = 100; 82 | 83 | // We'll set the Drop Sahdow on the second layer (we can add it to the SFPSDGroupOpeningLayer too) 84 | [secondLayer setDropShadowEffectLayerInformation:dropShadowInformation]; 85 | 86 | // Other available Effect Layers are: 87 | // - Inner Shadow (SFPSDInnerShadowEffectLayerInformation) 88 | // - Outer Glow (SFPSDOuterGlowEffectLayerInformation) 89 | // - Inner Glow (SFPSDInnerGlowEffectLayerInformation) 90 | // - Bevel (SFPSDBevelEffectLayerInformation) 91 | // - Solid Fill (SFPSDSolidFillEffectLayerInformation) 92 | 93 | // We have to close every group we've opened 94 | [psdWriter closeCurrentGroupLayer]; // second group 95 | [psdWriter closeCurrentGroupLayer]; // first group 96 | 97 | // We can change the embedded color profile of the document (for example with an "sRGB IEC61966-2.1") 98 | [psdWriter setColorProfile:SFPSDSRGBColorProfile]; 99 | 100 | // We'll write our test file into the documents folder of the application 101 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 102 | NSString *documentsDirectory = [paths objectAtIndex:0]; 103 | NSString *fullFilePath = [documentsDirectory stringByAppendingPathComponent:@"SFPSDWriter Test File.psd"]; 104 | 105 | // Retrieving the PSD data 106 | NSError *error = nil; 107 | NSData *psd = [psdWriter createPSDDataWithError:&error]; 108 | 109 | // Checking for errors 110 | if (nil != error) { 111 | NSLog(@"There was an error writing the PSD: %@", [error description]); 112 | return; 113 | } 114 | 115 | // Writing the data on disk 116 | // When using the simulator we can find the file in 117 | // /Users//Library/Application\ Support/iPhone\ Simulator//Applications//Documents 118 | [psd writeToFile:fullFilePath atomically:NO]; 119 | } 120 | 121 | - (void)applicationWillTerminate:(UIApplication *)application 122 | { 123 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 124 | } 125 | 126 | @end 127 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/SFPSDWriter iOS-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | net.shinyfrog.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | MainStoryboard_iPhone 29 | UIMainStoryboardFile~ipad 30 | MainStoryboard_iPad 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/SFPSDWriter iOS-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'SFPSDWriter iOS' target in the 'SFPSDWriter iOS' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_5_0 8 | #warning "This project uses features only available in iOS SDK 5.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/SFViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFViewController.h 3 | // SFPSDWriter iOS 4 | // 5 | // Created by Konstantin Erokhin on 11/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SFViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/SFViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SFViewController.m 3 | // SFPSDWriter iOS 4 | // 5 | // Created by Konstantin Erokhin on 11/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import "SFViewController.h" 10 | 11 | @interface SFViewController () 12 | 13 | @end 14 | 15 | @implementation SFViewController 16 | 17 | - (void)viewDidLoad 18 | { 19 | [super viewDidLoad]; 20 | // Do any additional setup after loading the view, typically from a nib. 21 | } 22 | 23 | - (void)didReceiveMemoryWarning 24 | { 25 | [super didReceiveMemoryWarning]; 26 | // Dispose of any resources that can be recreated. 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/en.lproj/MainStoryboard_iPad.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/en.lproj/MainStoryboard_iPhone.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Example Projects/SFPSDWriter iOS/SFPSDWriter iOS/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SFPSDWriter iOS 4 | // 5 | // Created by Konstantin Erokhin on 11/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SFAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SFAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Framework/SFPSDWriter.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Framework/SFPSDWriter/SFPSDWriter-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | net.shinyfrog.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | NSHumanReadableCopyright 26 | Copyright © 2014 Shiny Frog. All rights reserved. 27 | NSPrincipalClass 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Framework/SFPSDWriter/SFPSDWriter-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #endif 10 | -------------------------------------------------------------------------------- /Framework/SFPSDWriter/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Shiny Frog 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | 8 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | 10 | Neither the name of Shiny Frog nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Library/SFPSDWriter/Categories/NSData+SFPackedBits.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+SFPackedData.h 3 | // SFPSDWriter 4 | // 5 | // Created by Konstantin Erokhin on 06/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | // Inspired by PSDWriter by Ben Gotow ( https://github.com/bengotow/PSDWriter ) 9 | // 10 | 11 | #import 12 | 13 | @interface NSData (SFPackedBits) 14 | 15 | /** 16 | * Takes packedBits data and prints out a description of the packed contents by 17 | * running the decode operation and explaining via NSLog how the data is being 18 | * decoded. Useful for checking that packedBits data is correct. */ 19 | - (NSString *)sfPackedBitsDescription; 20 | 21 | /** 22 | * A special version of packedBits which will take the data and pack every nth 23 | * value. 24 | * 25 | * This is important for PSDWriter because it's necessary to encode R, then G, 26 | * then B, then A data - so we essentially start at offset 0, skip 4, then do offset 1, 27 | * skip 4, etc... to compress the data with very minimal memory footprint. 28 | * 29 | * For normal packbits just to skip = 1 30 | * 31 | * @param range: The range within the data object that should be encoded. Useful 32 | * for specifying a non-zero starting offset to get a certain channel encoded. 33 | * @param skip: The number of bytes to advance as the data is encoded. Skip = 1 will 34 | * encode every byte, skip = 4 will encode every fourth byte, and so on. */ 35 | - (NSData *)sfPackedBitsForRange:(NSRange)range skip:(int)skip; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Categories/NSData+SFPackedBits.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+SFPackedData.m 3 | // SFPSDWriter 4 | // 5 | // Created by Konstantin Erokhin on 06/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | // Inspired by PSDWriter by Ben Gotow ( https://github.com/bengotow/PSDWriter ) 9 | // 10 | 11 | #import "NSData+SFPackedBits.h" 12 | 13 | #define MIN_RUN 3 /* minimum run length to encode */ 14 | #define MAX_RUN 127 /* maximum run length to encode */ 15 | #define MAX_COPY 128 /* maximum characters to copy */ 16 | 17 | /* maximum that can be read before copy block is written */ 18 | #define MAX_READ (MAX_COPY + MIN_RUN - 1) 19 | 20 | @implementation NSData (SFPackedBits) 21 | 22 | - (NSString*)sfPackedBitsDescription 23 | { 24 | NSMutableString * description = [NSMutableString string]; 25 | char * row = (char*)[self bytes]; 26 | int pbOffset = 0; 27 | int pbResultBytes = 0; 28 | 29 | while (pbOffset < [self length]){ 30 | int headerByte = (int)row[pbOffset]; 31 | if (headerByte < 0){ 32 | int repeatTimes = 1-headerByte; 33 | UInt8 repeatByte = (UInt8)row[pbOffset+1]; 34 | [description appendFormat: @"Printing %u %d times. ", repeatByte, repeatTimes]; 35 | 36 | pbResultBytes += repeatTimes; 37 | pbOffset += 2; 38 | } else if (headerByte >= 0){ 39 | [description appendFormat: @"Printing %d literal bytes. ", headerByte + 1]; 40 | pbResultBytes += headerByte + 1; 41 | pbOffset += 2 + headerByte; 42 | } 43 | } 44 | 45 | [description appendFormat: @"Total: %d bytes decoded.", pbResultBytes]; 46 | return description; 47 | } 48 | 49 | - (NSData*)sfPackedBitsForRange:(NSRange)range skip:(int)skip 50 | { 51 | const char * bytesIn = [self bytes]; 52 | unsigned long bytesLength = range.location + range.length; 53 | unsigned long bytesOffset = range.location; 54 | NSMutableData * dataOut = [NSMutableData data]; 55 | 56 | BOOL currIsEOF = NO; 57 | unsigned char currChar; /* current character */ 58 | unsigned char charBuf[MAX_READ]; /* buffer of already read characters */ 59 | int count; /* number of characters in a run */ 60 | 61 | /* prime the read loop */ 62 | currChar = bytesIn[bytesOffset]; 63 | bytesOffset = bytesOffset + skip; 64 | count = 0; 65 | 66 | /* read input until there's nothing left */ 67 | while (!currIsEOF) 68 | { 69 | charBuf[count] = (unsigned char)currChar; 70 | count++; 71 | 72 | if (count >= MIN_RUN) { 73 | int i; 74 | /* check for run charBuf[count - 1] .. charBuf[count - MIN_RUN]*/ 75 | for (i = 2; i <= MIN_RUN; i++){ 76 | if (currChar != charBuf[count - i]){ 77 | /* no run */ 78 | i = 0; 79 | break; 80 | } 81 | } 82 | 83 | if (i != 0) 84 | { 85 | /* we have a run write out buffer before run*/ 86 | int nextChar; 87 | 88 | if (count > MIN_RUN){ 89 | /* block size - 1 followed by contents */ 90 | UInt8 a = count - MIN_RUN - 1; 91 | [dataOut appendBytes:&a length:sizeof(UInt8)]; 92 | [dataOut appendBytes:&charBuf length:sizeof(unsigned char) * (count - MIN_RUN)]; 93 | } 94 | 95 | /* determine run length (MIN_RUN so far) */ 96 | count = MIN_RUN; 97 | while (true) { 98 | if (bytesOffset < bytesLength){ 99 | nextChar = bytesIn[bytesOffset]; 100 | bytesOffset += skip; 101 | } else { 102 | currIsEOF = YES; 103 | nextChar = EOF; 104 | } 105 | if (nextChar != currChar) break; 106 | 107 | count++; 108 | if (count == MAX_RUN){ 109 | /* run is at max length */ 110 | break; 111 | } 112 | } 113 | 114 | /* write out encoded run length and run symbol */ 115 | UInt8 a = ((int)(1 - (int)(count))); 116 | [dataOut appendBytes:&a length:sizeof(UInt8)]; 117 | [dataOut appendBytes:&currChar length:sizeof(UInt8)]; 118 | 119 | if ((!currIsEOF) && (count != MAX_RUN)){ 120 | /* make run breaker start of next buffer */ 121 | charBuf[0] = nextChar; 122 | count = 1; 123 | } else { 124 | /* file or max run ends in a run */ 125 | count = 0; 126 | } 127 | } 128 | } 129 | 130 | if (count == MAX_READ) 131 | { 132 | int i; 133 | 134 | /* write out buffer */ 135 | UInt8 a = MAX_COPY - 1; 136 | [dataOut appendBytes:&a length:sizeof(UInt8)]; 137 | [dataOut appendBytes:&charBuf[0] length:sizeof(unsigned char) * MAX_COPY]; 138 | 139 | /* start a new buffer */ 140 | count = MAX_READ - MAX_COPY; 141 | 142 | /* copy excess to front of buffer */ 143 | for (i = 0; i < count; i++) 144 | charBuf[i] = charBuf[MAX_COPY + i]; 145 | } 146 | 147 | if (bytesOffset < bytesLength) 148 | currChar = bytesIn[bytesOffset]; 149 | else 150 | currIsEOF = YES; 151 | bytesOffset += skip; 152 | } 153 | 154 | /* write out last buffer */ 155 | if (0 != count) 156 | { 157 | if (count <= MAX_COPY) { 158 | /* write out entire copy buffer */ 159 | UInt8 a = count - 1; 160 | [dataOut appendBytes:&a length:sizeof(UInt8)]; 161 | [dataOut appendBytes:&charBuf length:sizeof(unsigned char) * count]; 162 | } 163 | else 164 | { 165 | /* we read more than the maximum for a single copy buffer */ 166 | UInt8 a = MAX_COPY - 1; 167 | [dataOut appendBytes:&a length:sizeof(UInt8)]; 168 | [dataOut appendBytes:&charBuf length:sizeof(unsigned char) * MAX_COPY]; 169 | 170 | /* write out remainder */ 171 | count -= MAX_COPY; 172 | a = count - 1; 173 | [dataOut appendBytes:&a length:sizeof(UInt8)]; 174 | [dataOut appendBytes:&charBuf[MAX_COPY] length:sizeof(unsigned char) * count]; 175 | } 176 | } 177 | 178 | return dataOut; 179 | 180 | } 181 | 182 | @end 183 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Categories/NSMutableData+SFAppendValue.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableData+SFAppendValue.h 3 | // SFPSDWriter 4 | // 5 | // Created by Konstantin Erokhin on 06/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | // Inspired by PSDWriter by Ben Gotow ( https://github.com/bengotow/PSDWriter ) 9 | // 10 | 11 | #import 12 | 13 | 14 | @interface NSMutableData (SFAppendValue) 15 | 16 | /** 17 | * Allows you to append a numeric value to an NSMutableData object and pad it to any length. 18 | * 19 | * For example, we could say [data appendValue: 2 withLength: 5], and 00002 would be written 20 | * into the data object. Very useful for writing to file formats that have header structures 21 | * that require a certain number of bytes be used for a certain value. i.e. PSD and TIFF 22 | * 23 | * @param value: The value to append 24 | * @param length: The number of bytes that should be used to store the value. The value will be padded 25 | * to length bytes regardless of the number of bytes required to store it. */ 26 | - (void)sfAppendValue:(long)value length:(int)length; 27 | 28 | /** Allows you to append a NSString to the NSMutableData object. */ 29 | - (void)sfAppendUTF8String:(NSString *)value length:(int)length; 30 | 31 | /** Allows you to append a "Native" CGColorRef to the NSMutableData object. 32 | * For example it is used in the Effects Layer in the Additional Layer Information to write the 33 | * layer effect color */ 34 | - (void)sfAppendCGColorRef:(CGColorRef)color length:(int)length; 35 | 36 | @end -------------------------------------------------------------------------------- /Library/SFPSDWriter/Categories/NSMutableData+SFAppendValue.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableData+SFAppendValue.m 3 | // SFPSDWriter 4 | // 5 | // Created by Konstantin Erokhin on 06/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | // Inspired by PSDWriter by Ben Gotow ( https://github.com/bengotow/PSDWriter ) 9 | // 10 | 11 | #import "NSMutableData+SFAppendValue.h" 12 | 13 | @implementation NSMutableData (SFAppendValue) 14 | 15 | - (void)sfAppendValue:(long)value length:(int)length 16 | { 17 | Byte bytes[8]; 18 | 19 | double divider = 1; 20 | for (int i = 0; i < length; i++){ 21 | bytes[length - i - 1] = (long)(value / divider) % 256; 22 | divider *= 256; 23 | } 24 | 25 | [self appendBytes:&bytes length:length]; 26 | } 27 | 28 | - (void)sfAppendUTF8String:(NSString *)value length:(int)length 29 | { 30 | NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding]; 31 | [self appendData:data]; 32 | } 33 | 34 | - (void)sfAppendCGColorRef:(CGColorRef)color length:(int)length 35 | { 36 | const CGFloat *colorComponents = CGColorGetComponents(color); 37 | size_t numberOfComponents = CGColorGetNumberOfComponents(color); 38 | 39 | NSAssert(numberOfComponents == 4, @"The color components should always be 4 (RGBA color)"); 40 | 41 | UInt32 redComponent = colorComponents[0] * 65536.0 - 0.5; 42 | UInt32 greenComponent = colorComponents[1] * 65536.0 - 0.5; 43 | UInt32 blueComponent = colorComponents[2] * 65536.0 - 0.5; 44 | //UInt32 alphaComponent = colorComponents[3] * 65536.0 - 0.5; 45 | 46 | // NSLog(@"RGBA(%d, %d, %d, %d)", redComponent, greenComponent, blueComponent, alphaComponent); 47 | 48 | [self sfAppendValue:0 length:2]; // 2 bytes for space 49 | [self sfAppendValue:redComponent length:2]; // followed by 4 * 2 byte color component 50 | [self sfAppendValue:greenComponent length:2]; 51 | [self sfAppendValue:blueComponent length:2]; 52 | [self sfAppendValue:0 length:2]; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Categories/NSString+SFPascalString.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+SFPascalString.h 3 | // SFPSDWriter 4 | // 5 | // Created by Konstantin Erokhin on 06/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | // Inspired by PSDWriter by Ben Gotow ( https://github.com/bengotow/PSDWriter ) 9 | // 10 | 11 | #import 12 | 13 | @interface NSString (SFPascalString) 14 | 15 | /** Pascal string padded to multiples of the paddind interval. */ 16 | - (const char *)sfPascalStringPaddedTo:(int)paddingInterval withPaddingString:(NSString *)paddingString; 17 | 18 | /** Pascal string padded to multiples of the paddind interval using as padding the unicode char 0x00. */ 19 | - (const char *)sfPascalStringPaddedTo:(int)paddingInterval; 20 | 21 | /** The length of the string padded to the multiples of the padding interval. */ 22 | - (int)sfPascalStringLengthPaddedTo:(int)paddingInterval; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Categories/NSString+SFPascalString.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+SFPascalString.m 3 | // SFPSDWriter 4 | // 5 | // Created by Konstantin Erokhin on 06/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | // Inspired by PSDWriter by Ben Gotow ( https://github.com/bengotow/PSDWriter ) 9 | // 10 | 11 | #import "NSString+SFPascalString.h" 12 | 13 | @implementation NSString (SFPascalString) 14 | 15 | - (const char *)sfPascalStringPaddedTo:(int)paddingInterval withPaddingString:(NSString *)paddingString 16 | { 17 | int paddedStringLength = [self sfPascalStringLengthPaddedTo:paddingInterval]; 18 | NSString *paddedString = [self stringByPaddingToLength:paddedStringLength withString:paddingString startingAtIndex:0]; 19 | return [paddedString UTF8String]; 20 | } 21 | 22 | - (const char *)sfPascalStringPaddedTo:(int)paddingInterval 23 | { 24 | const unichar zero = 0x00; 25 | NSString *paddingString = [NSString stringWithCharacters:(unichar *)&zero length:1]; 26 | return [self sfPascalStringPaddedTo:paddingInterval withPaddingString:paddingString]; 27 | } 28 | 29 | - (int)sfPascalStringLengthPaddedTo:(int)paddingInterval 30 | { 31 | int paddingsIntervals = (int)ceilf((float)[self length] / (float)paddingInterval); 32 | return paddingsIntervals * paddingInterval; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/ICCProfileData/AdobeRGB1998: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Library/SFPSDWriter/ICCProfileData/AdobeRGB1998 -------------------------------------------------------------------------------- /Library/SFPSDWriter/ICCProfileData/GenericRGB: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Library/SFPSDWriter/ICCProfileData/GenericRGB -------------------------------------------------------------------------------- /Library/SFPSDWriter/ICCProfileData/sRGB: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinyfrog/SFPSDWriter/21e81c469afb4b148e8c73b12f5bedf0cec16f6d/Library/SFPSDWriter/ICCProfileData/sRGB -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Constants/SFPSDEffectsLayerEffectSignatures.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDEffectsLayerEffectSignatures.h 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 15/06/14. 6 | // Copyright (c) 2014 Shiny Frog. All rights reserved. 7 | // 8 | // Inspired by PSDWriter by Ben Gotow ( https://github.com/bengotow/PSDWriter ) 9 | // 10 | 11 | extern NSString* const SFPSDEffectsLayerEffectSignatureCommonState; 12 | extern NSString* const SFPSDEffectsLayerEffectSignatureDropShadow; 13 | extern NSString* const SFPSDEffectsLayerEffectSignatureInnerShadow; 14 | extern NSString* const SFPSDEffectsLayerEffectSignatureOuterGlow; 15 | extern NSString* const SFPSDEffectsLayerEffectSignatureInnerGlow; 16 | extern NSString* const SFPSDEffectsLayerEffectSignatureBevel; 17 | extern NSString* const SFPSDEffectsLayerEffectSignatureSolidFill; -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Constants/SFPSDEffectsLayerEffectSignatures.m: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDEffectsLayerEffectSignatures.m 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 15/06/14. 6 | // Copyright (c) 2014 Shiny Frog. All rights reserved. 7 | // 8 | // Inspired by PSDWriter by Ben Gotow ( https://github.com/bengotow/PSDWriter ) 9 | // 10 | 11 | NSString* const SFPSDEffectsLayerEffectSignatureCommonState = @"cmnS"; 12 | NSString* const SFPSDEffectsLayerEffectSignatureDropShadow = @"dsdw"; 13 | NSString* const SFPSDEffectsLayerEffectSignatureInnerShadow = @"isdw"; 14 | NSString* const SFPSDEffectsLayerEffectSignatureOuterGlow = @"oglw"; 15 | NSString* const SFPSDEffectsLayerEffectSignatureInnerGlow = @"iglw"; 16 | NSString* const SFPSDEffectsLayerEffectSignatureBevel = @"bevl"; 17 | NSString* const SFPSDEffectsLayerEffectSignatureSolidFill = @"sofi"; -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Constants/SFPSDLayerBlendModes.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDLayerBlendModes.h 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 06/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | // Inspired by PSDWriter by Ben Gotow ( https://github.com/bengotow/PSDWriter ) 9 | // 10 | 11 | extern NSString* const SFPSDLayerBlendModeNormal; 12 | extern NSString* const SFPSDLayerBlendModeDarken; 13 | extern NSString* const SFPSDLayerBlendModeLighten; 14 | extern NSString* const SFPSDLayerBlendModeHue; 15 | extern NSString* const SFPSDLayerBlendModeSaturation; 16 | extern NSString* const SFPSDLayerBlendModeColor; 17 | extern NSString* const SFPSDLayerBlendModeLuminosity; 18 | extern NSString* const SFPSDLayerBlendModeMultiply; 19 | extern NSString* const SFPSDLayerBlendModeScreen; 20 | extern NSString* const SFPSDLayerBlendModeDissolve; 21 | extern NSString* const SFPSDLayerBlendModeOverlay; 22 | extern NSString* const SFPSDLayerBlendModeHardLight; 23 | extern NSString* const SFPSDLayerBlendModeSoftLight; 24 | extern NSString* const SFPSDLayerBlendModeDifference; 25 | extern NSString* const SFPSDLayerBlendModeExclusion; 26 | extern NSString* const SFPSDLayerBlendModeColorDodge; 27 | extern NSString* const SFPSDLayerBlendModeColorBurn; 28 | extern NSString* const SFPSDLayerBlendModeLinearBurn; 29 | extern NSString* const SFPSDLayerBlendModeLinearDodge; 30 | extern NSString* const SFPSDLayerBlendModeVividLight; 31 | extern NSString* const SFPSDLayerBlendModeLinearLight; 32 | extern NSString* const SFPSDLayerBlendModePinLight; 33 | extern NSString* const SFPSDLayerBlendModeHardMix; 34 | extern NSString* const SFPSDLayerBlendModePassThrough; 35 | extern NSString* const SFPSDLayerBlendModeDarkerColor; 36 | extern NSString* const SFPSDLayerBlendModeLighterColor; 37 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Constants/SFPSDLayerBlendModes.m: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDLayerBlendModes.m 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 06/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | // Inspired by PSDWriter by Ben Gotow ( https://github.com/bengotow/PSDWriter ) 9 | // 10 | 11 | NSString* const SFPSDLayerBlendModeNormal = @"norm"; 12 | NSString* const SFPSDLayerBlendModeDarken = @"dark"; 13 | NSString* const SFPSDLayerBlendModeLighten = @"lite"; 14 | NSString* const SFPSDLayerBlendModeHue = @"hue "; 15 | NSString* const SFPSDLayerBlendModeSaturation = @"sat "; 16 | NSString* const SFPSDLayerBlendModeColor = @"colr"; 17 | NSString* const SFPSDLayerBlendModeLuminosity = @"lum "; 18 | NSString* const SFPSDLayerBlendModeMultiply = @"mul "; 19 | NSString* const SFPSDLayerBlendModeScreen = @"scrn"; 20 | NSString* const SFPSDLayerBlendModeDissolve = @"diss"; 21 | NSString* const SFPSDLayerBlendModeOverlay = @"over"; 22 | NSString* const SFPSDLayerBlendModeHardLight = @"hLit"; 23 | NSString* const SFPSDLayerBlendModeSoftLight = @"sLit"; 24 | NSString* const SFPSDLayerBlendModeDifference = @"diff"; 25 | NSString* const SFPSDLayerBlendModeExclusion = @"smud"; 26 | NSString* const SFPSDLayerBlendModeColorDodge = @"div "; 27 | NSString* const SFPSDLayerBlendModeColorBurn = @"idiv"; 28 | NSString* const SFPSDLayerBlendModeLinearBurn = @"lbrn"; 29 | NSString* const SFPSDLayerBlendModeLinearDodge = @"lddg"; 30 | NSString* const SFPSDLayerBlendModeVividLight = @"vLit"; 31 | NSString* const SFPSDLayerBlendModeLinearLight = @"lLit"; 32 | NSString* const SFPSDLayerBlendModePinLight = @"pLit"; 33 | NSString* const SFPSDLayerBlendModeHardMix = @"hMix"; 34 | NSString* const SFPSDLayerBlendModePassThrough = @"pass"; 35 | NSString* const SFPSDLayerBlendModeDarkerColor = @"dkCl"; 36 | NSString* const SFPSDLayerBlendModeLighterColor = @"lgCl"; 37 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Effect Layer Information Classes/SFPSDBevelEffectLayerInformation.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDBevelEffectLayerInformation.h 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 15/06/14. 6 | // Copyright (c) 2014 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SFPSDLayerBlendModes.h" 11 | 12 | typedef enum { 13 | SFPSDBevelEffectLayerInformationStyleOuterBevel = 1, 14 | SFPSDBevelEffectLayerInformationStyleInnerBevel = 2, 15 | SFPSDBevelEffectLayerInformationStyleEmboss = 3, 16 | SFPSDBevelEffectLayerInformationStylePillowEmboss = 4, 17 | SFPSDBevelEffectLayerInformationStyleStrokeEmboss = 5 18 | } SFPSDBevelEffectLayerInformationStyle; 19 | 20 | typedef enum { 21 | SFPSDBevelEffectLayerInformationDirectionUp = 0, 22 | SFPSDBevelEffectLayerInformationDirectionDown = 1 23 | 24 | } SFPSDBevelEffectLayerInformationDirection; 25 | 26 | @interface SFPSDBevelEffectLayerInformation : NSObject 27 | 28 | /** "Angle" Bevel effect configuration inside Photoshop (-360...360) */ 29 | @property (nonatomic, assign) long angle; 30 | /** "Size" Bevel effect configuration inside Photoshop (0...250) */ 31 | @property (nonatomic, assign) long size; 32 | /** "Highlight Blend Mode" Bevel effect configuration inside Photoshop */ 33 | @property (nonatomic, strong) NSString *highlightBlendMode; 34 | /** "Shadow Blend Mode" Bevel effect configuration inside Photoshop */ 35 | @property (nonatomic, strong) NSString *shadowBlendMode; 36 | /** Highlight Color Bevel effect configuration inside Photoshop */ 37 | @property (nonatomic, assign) CGColorRef highlightColor; 38 | /** Shadow Color Bevel effect configuration inside Photoshop */ 39 | @property (nonatomic, assign) CGColorRef shadowColor; 40 | /** "Style" Bevel effect configuration inside Photoshop */ 41 | @property (nonatomic, assign) SFPSDBevelEffectLayerInformationStyle style; 42 | /** "Highlight Opacity" Bevel effect configuration inside Photoshop (0...100) */ 43 | @property (nonatomic, assign) long highlightOpacity; 44 | /** "Shadow Opacity" Bevel effect configuration inside Photoshop (0...100) */ 45 | @property (nonatomic, assign) long shadowOpacity; 46 | /** Set to YES in order to enable the effect */ 47 | @property (nonatomic, assign) BOOL enabled; 48 | /** "Use Global Light" Bevel effect configuration inside Photoshop */ 49 | @property (nonatomic, assign) BOOL useGlobalLight; 50 | /** "Direction" Bevel effect configuration inside Photoshop */ 51 | @property (nonatomic, assign) SFPSDBevelEffectLayerInformationDirection direction; 52 | 53 | /** Return a (0...255) value for the highlight opacity */ 54 | - (long)highlightOpacity255; 55 | /** Return a (0...255) value for the shadow opacity */ 56 | - (long)shadowOpacity255; 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Effect Layer Information Classes/SFPSDBevelEffectLayerInformation.m: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDBevelEffectLayerInformation.m 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 15/06/14. 6 | // Copyright (c) 2014 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import "SFPSDBevelEffectLayerInformation.h" 10 | 11 | @implementation SFPSDBevelEffectLayerInformation 12 | 13 | @synthesize angle = _angle, size = _size, highlightBlendMode = _highlightBlendMode, shadowBlendMode = _shadowBlendMode, highlightColor = _highlightColor, shadowColor = _shadowColor, style = _style, highlightOpacity = _highlightOpacity, shadowOpacity = _shadowOpacity, enabled = _enabled, useGlobalLight = _useGlobalLight, direction = _direction; 14 | 15 | - (id)init 16 | { 17 | self = [super init]; 18 | if (self) 19 | { 20 | _angle = 0; 21 | _size = 0; 22 | _highlightBlendMode = SFPSDLayerBlendModeNormal; 23 | _shadowBlendMode = SFPSDLayerBlendModeNormal; 24 | 25 | CGFloat components[4] = {0.0,0.0,0.0,0.0}; 26 | _highlightColor = CGColorCreate(CGColorSpaceCreateDeviceRGB(), components); 27 | _shadowColor = CGColorCreate(CGColorSpaceCreateDeviceRGB(), components); 28 | 29 | _style = SFPSDBevelEffectLayerInformationStyleOuterBevel; 30 | _highlightOpacity = 100; 31 | _shadowOpacity = 100; 32 | _enabled = NO; 33 | _useGlobalLight = YES; 34 | _direction = SFPSDBevelEffectLayerInformationDirectionDown; 35 | } 36 | return self; 37 | } 38 | 39 | - (void)setAngle:(long)angle 40 | { 41 | if (angle < -360) { 42 | angle = -360; 43 | } 44 | else if (angle > 360) { 45 | angle = 360; 46 | } 47 | _angle = angle; 48 | } 49 | 50 | - (void)setSize:(long)size 51 | { 52 | if (size < 0) { 53 | size = 0; 54 | } 55 | else if (size > 250) { 56 | size = 250; 57 | } 58 | _size = size; 59 | } 60 | 61 | - (void)setHighlightOpacity:(long)opacity 62 | { 63 | if (opacity < 0) { 64 | opacity = 0; 65 | } 66 | else if (opacity > 255) { 67 | opacity = 255; 68 | } 69 | _highlightOpacity = opacity; 70 | } 71 | 72 | - (void)setShadowOpacity:(long)opacity 73 | { 74 | if (opacity < 0) { 75 | opacity = 0; 76 | } 77 | else if (opacity > 255) { 78 | opacity = 255; 79 | } 80 | _shadowOpacity = opacity; 81 | } 82 | 83 | - (long)highlightOpacity255 84 | { 85 | return 2.55 * _highlightOpacity; 86 | } 87 | 88 | - (long)shadowOpacity255 89 | { 90 | return 2.55 * _shadowOpacity; 91 | } 92 | 93 | @end -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Effect Layer Information Classes/SFPSDDropShadowEffectLayerInformation.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDDropShadowEffectLayerInformation.h 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 15/06/14. 6 | // Copyright (c) 2014 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SFPSDLayerBlendModes.h" 11 | 12 | @interface SFPSDDropShadowEffectLayerInformation : NSObject 13 | { 14 | } 15 | 16 | /** "Size" Drop Shadow effect configuration inside Photoshop (0...250) */ 17 | @property (nonatomic, assign) long size; 18 | /** "Angle" Drop Shadow effect configuration inside Photoshop (-360...360) */ 19 | @property (nonatomic, assign) long angle; 20 | /** "Distance" Drop Shadow effect configuration inside Photoshop (0...30000) */ 21 | @property (nonatomic, assign) long distance; 22 | /** Color Drop Shadow effect configuration inside Photoshop */ 23 | @property (nonatomic, assign) CGColorRef color; 24 | /** "Blend Mode" Drop Shadow effect configuration inside Photoshop */ 25 | @property (nonatomic, strong) NSString *blendMode; 26 | /** Set to YES in order to enable the effect */ 27 | @property (nonatomic, assign) BOOL enabled; 28 | /** "Use Global Light" Drop Shadow effect configuration inside Photoshop */ 29 | @property (nonatomic, assign) BOOL useGlobalLight; 30 | /** "Opacity" Drop Shadow effect configuration inside Photoshop (0...100) */ 31 | @property (nonatomic, assign) long opacity; 32 | 33 | /** Return a (0...255) value for the opacity */ 34 | - (long)opacity255; 35 | 36 | @end 37 | 38 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Effect Layer Information Classes/SFPSDDropShadowEffectLayerInformation.m: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDDropShadowEffectLayerInformation.m 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 15/06/14. 6 | // Copyright (c) 2014 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import "SFPSDDropShadowEffectLayerInformation.h" 10 | 11 | @implementation SFPSDDropShadowEffectLayerInformation 12 | 13 | @synthesize size = _size, angle = _angle, distance = _distance, color = _color, blendMode = _blendMode, enabled = _enabled, useGlobalLight = _useGlobalLight, opacity = _opacity; 14 | 15 | - (id)init 16 | { 17 | self = [super init]; 18 | if (self) 19 | { 20 | _size = 0; 21 | _angle = 0; 22 | _distance = 0; 23 | 24 | CGFloat components[4] = {0.0,0.0,0.0,0.0}; 25 | _color = CGColorCreate(CGColorSpaceCreateDeviceRGB(), components); 26 | 27 | _blendMode = SFPSDLayerBlendModeNormal; 28 | _enabled = NO; 29 | _useGlobalLight = NO; 30 | _opacity = 100; 31 | } 32 | return self; 33 | } 34 | 35 | - (void)setSize:(long)size 36 | { 37 | if (size < 0) { 38 | size = 0; 39 | } 40 | else if (size > 250) { 41 | size = 250; 42 | } 43 | _size = size; 44 | } 45 | 46 | - (void)setAngle:(long)angle 47 | { 48 | if (angle < -360) { 49 | angle = -360; 50 | } 51 | else if (angle > 360) { 52 | angle = 360; 53 | } 54 | _angle = angle; 55 | } 56 | 57 | - (void)setDistance:(long)distance 58 | { 59 | if (distance < 0) { 60 | distance = 0; 61 | } 62 | else if (distance > 30000) { 63 | distance = 30000; 64 | } 65 | _distance = distance; 66 | } 67 | 68 | - (void)setOpacity:(long)opacity 69 | { 70 | if (opacity < 0) { 71 | opacity = 0; 72 | } 73 | else if (opacity > 100) { 74 | opacity = 100; 75 | } 76 | _opacity = opacity; 77 | } 78 | 79 | - (long)opacity255 80 | { 81 | return 2.55 * _opacity; 82 | } 83 | 84 | @end -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Effect Layer Information Classes/SFPSDEffectLayerInformations.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDEffectLayerInformations.h 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 15/06/14. 6 | // Copyright (c) 2014 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import "SFPSDDropShadowEffectLayerInformation.h" 10 | #import "SFPSDInnerShadowEffectLayerInformation.h" 11 | #import "SFPSDOuterGlowEffectLayerInformation.h" 12 | #import "SFPSDInnerGlowEffectLayerInformation.h" 13 | #import "SFPSDBevelEffectLayerInformation.h" 14 | #import "SFPSDSolidFillEffectLayerInformation.h" -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Effect Layer Information Classes/SFPSDInnerGlowEffectLayerInformation.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDInnerGlowEffectLayerInformation.h 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 15/06/14. 6 | // Copyright (c) 2014 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SFPSDLayerBlendModes.h" 11 | 12 | typedef enum { 13 | SFPSDInnerGlowEffectLayerInformationSourceCenter = 0, 14 | SFPSDInnerGlowEffectLayerInformationSourceEdge = 1 15 | } SFPSDInnerGlowEffectLayerInformationSource; 16 | 17 | @interface SFPSDInnerGlowEffectLayerInformation : NSObject 18 | 19 | /** "Size" Inner Glow effect configuration inside Photoshop (0...250) */ 20 | @property (nonatomic, assign) long size; 21 | /** Color Inner Glow effect configuration inside Photoshop */ 22 | @property (nonatomic, assign) CGColorRef color; 23 | /** "Blend Mode" Inner Glow effect configuration inside Photoshop */ 24 | @property (nonatomic, strong) NSString *blendMode; 25 | /** Set to YES in order to enable the effect */ 26 | @property (nonatomic, assign) BOOL enabled; 27 | /** "Opacity" Inner Glow effect configuration inside Photoshop (0...100) */ 28 | @property (nonatomic, assign) long opacity; 29 | /** "Source" Inner Glow effect configuration inside Photoshop */ 30 | @property (nonatomic, assign) SFPSDInnerGlowEffectLayerInformationSource source; 31 | 32 | /** Return a (0...255) value for the opacity */ 33 | - (long)opacity255; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Effect Layer Information Classes/SFPSDInnerGlowEffectLayerInformation.m: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDInnerGlowEffectLayerInformation.m 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 15/06/14. 6 | // Copyright (c) 2014 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import "SFPSDInnerGlowEffectLayerInformation.h" 10 | 11 | @implementation SFPSDInnerGlowEffectLayerInformation 12 | 13 | @synthesize size = _size, color = _color, blendMode = _blendMode, enabled = _enabled, opacity = _opacity, source = _source; 14 | 15 | - (id)init 16 | { 17 | self = [super init]; 18 | if (self) 19 | { 20 | _size = 0; 21 | 22 | CGFloat components[4] = {0.0,0.0,0.0,0.0}; 23 | _color = CGColorCreate(CGColorSpaceCreateDeviceRGB(), components); 24 | 25 | _blendMode = SFPSDLayerBlendModeNormal; 26 | _enabled = NO; 27 | _opacity = 100; 28 | _source = SFPSDInnerGlowEffectLayerInformationSourceCenter; 29 | } 30 | return self; 31 | } 32 | 33 | - (void)setSize:(long)size 34 | { 35 | if (size < 0) { 36 | size = 0; 37 | } 38 | else if (size > 250) { 39 | size = 250; 40 | } 41 | _size = size; 42 | } 43 | 44 | - (void)setOpacity:(long)opacity 45 | { 46 | if (opacity < 0) { 47 | opacity = 0; 48 | } 49 | else if (opacity > 100) { 50 | opacity = 100; 51 | } 52 | _opacity = opacity; 53 | } 54 | 55 | - (long)opacity255 56 | { 57 | return 2.55 * _opacity; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Effect Layer Information Classes/SFPSDInnerShadowEffectLayerInformation.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDInnerShadowEffectLayerInformation.h 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 15/06/14. 6 | // Copyright (c) 2014 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SFPSDLayerBlendModes.h" 11 | 12 | @interface SFPSDInnerShadowEffectLayerInformation : NSObject 13 | 14 | /** "Size" Inner Shadow effect configuration inside Photoshop (0...250) */ 15 | @property (nonatomic, assign) long size; 16 | /** "Angle" Inner Shadow effect configuration inside Photoshop (-360...360) */ 17 | @property (nonatomic, assign) long angle; 18 | /** "Distance" Inner Shadow effect configuration inside Photoshop (0...30000) */ 19 | @property (nonatomic, assign) long distance; 20 | /** Color Inner Shadow effect configuration inside Photoshop */ 21 | @property (nonatomic, assign) CGColorRef color; 22 | /** "Belnd Mode" Inner Shadow effect configuration inside Photoshop */ 23 | @property (nonatomic, strong) NSString *blendMode; 24 | /** Set to YES in order to enable the effect */ 25 | @property (nonatomic, assign) BOOL enabled; 26 | /** "Use Global Light" Inner Shadow effect configuration inside Photoshop */ 27 | @property (nonatomic, assign) BOOL useGlobalLight; 28 | /** "Opacity" Inner Shadow effect configuration inside Photoshop (0...100) */ 29 | @property (nonatomic, assign) long opacity; 30 | 31 | /** Return a (0...255) value for the opacity */ 32 | - (long)opacity255; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Effect Layer Information Classes/SFPSDInnerShadowEffectLayerInformation.m: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDInnerShadowEffectLayerInformation.m 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 15/06/14. 6 | // Copyright (c) 2014 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import "SFPSDInnerShadowEffectLayerInformation.h" 10 | 11 | @implementation SFPSDInnerShadowEffectLayerInformation 12 | 13 | @synthesize size = _size, angle = _angle, distance = _distance, color = _color, blendMode = _blendMode, enabled = _enabled, useGlobalLight = _useGlobalLight, opacity = _opacity; 14 | 15 | - (id)init 16 | { 17 | self = [super init]; 18 | if (self) 19 | { 20 | _size = 0; 21 | _angle = 0; 22 | _distance = 0; 23 | 24 | CGFloat components[4] = {0.0,0.0,0.0,0.0}; 25 | _color = CGColorCreate(CGColorSpaceCreateDeviceRGB(), components); 26 | 27 | _blendMode = SFPSDLayerBlendModeNormal; 28 | _enabled = NO; 29 | _useGlobalLight = NO; 30 | _opacity = 100; 31 | } 32 | return self; 33 | } 34 | 35 | - (void)setSize:(long)size 36 | { 37 | if (size < 0) { 38 | size = 0; 39 | } 40 | else if (size > 250) { 41 | size = 250; 42 | } 43 | _size = size; 44 | } 45 | 46 | - (void)setAngle:(long)angle 47 | { 48 | if (angle < -360) { 49 | angle = -360; 50 | } 51 | else if (angle > 360) { 52 | angle = 360; 53 | } 54 | _angle = angle; 55 | } 56 | 57 | - (void)setDistance:(long)distance 58 | { 59 | if (distance < 0) { 60 | distance = 0; 61 | } 62 | else if (distance > 30000) { 63 | distance = 30000; 64 | } 65 | _distance = distance; 66 | } 67 | 68 | - (void)setOpacity:(long)opacity 69 | { 70 | if (opacity < 0) { 71 | opacity = 0; 72 | } 73 | else if (opacity > 100) { 74 | opacity = 100; 75 | } 76 | _opacity = opacity; 77 | } 78 | 79 | - (long)opacity255 80 | { 81 | return 2.55 * _opacity; 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Effect Layer Information Classes/SFPSDOuterGlowEffectLayerInformation.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDOuterGlowEffectLayerInformation.h 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 15/06/14. 6 | // Copyright (c) 2014 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SFPSDLayerBlendModes.h" 11 | 12 | @interface SFPSDOuterGlowEffectLayerInformation : NSObject 13 | 14 | /** "Size" Outer Glow effect configuration inside Photoshop (0...250) */ 15 | @property (nonatomic, assign) long size; 16 | /** Color Outer Glow effect configuration inside Photoshop */ 17 | @property (nonatomic, assign) CGColorRef color; 18 | /** "Blend Mode" Outer Glow effect configuration inside Photoshop */ 19 | @property (nonatomic, strong) NSString *blendMode; 20 | /** Set to YES in order to enable the effect */ 21 | @property (nonatomic, assign) BOOL enabled; 22 | /** "Opacity" Outer Glow effect configuration inside Photoshop (0...100) */ 23 | @property (nonatomic, assign) long opacity; 24 | 25 | /** Return a (0...255) value for the opacity */ 26 | - (long)opacity255; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Effect Layer Information Classes/SFPSDOuterGlowEffectLayerInformation.m: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDOuterGlowEffectLayerInformation.m 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 15/06/14. 6 | // Copyright (c) 2014 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import "SFPSDOuterGlowEffectLayerInformation.h" 10 | 11 | @implementation SFPSDOuterGlowEffectLayerInformation 12 | 13 | @synthesize size = _size, color = _color, blendMode = _blendMode, enabled = _enabled, opacity = _opacity; 14 | 15 | - (id)init 16 | { 17 | self = [super init]; 18 | if (self) 19 | { 20 | _size = 0; 21 | 22 | CGFloat components[4] = {0.0,0.0,0.0,0.0}; 23 | _color = CGColorCreate(CGColorSpaceCreateDeviceRGB(), components); 24 | 25 | _blendMode = SFPSDLayerBlendModeNormal; 26 | _enabled = NO; 27 | _opacity = 100; 28 | } 29 | return self; 30 | } 31 | 32 | - (void)setSize:(long)size 33 | { 34 | if (size < 0) { 35 | size = 0; 36 | } 37 | else if (size > 250) { 38 | size = 250; 39 | } 40 | _size = size; 41 | } 42 | 43 | - (void)setOpacity:(long)opacity 44 | { 45 | if (opacity < 0) { 46 | opacity = 0; 47 | } 48 | else if (opacity > 100) { 49 | opacity = 100; 50 | } 51 | _opacity = opacity; 52 | } 53 | 54 | - (long)opacity255 55 | { 56 | return 2.55 * _opacity; 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Effect Layer Information Classes/SFPSDSolidFillEffectLayerInformation.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDSolidFillEffectLayerInformation.h 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 15/06/14. 6 | // Copyright (c) 2014 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SFPSDLayerBlendModes.h" 11 | 12 | @interface SFPSDSolidFillEffectLayerInformation : NSObject 13 | 14 | @property (nonatomic, strong) NSString *blendMode; 15 | @property (nonatomic, assign) CGColorRef color; 16 | @property (nonatomic, assign) long opacity; // (0...100) 17 | @property (nonatomic, assign) BOOL enabled; 18 | 19 | - (long)opacity255; // (0...255) 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/Effect Layer Information Classes/SFPSDSolidFillEffectLayerInformation.m: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDSolidFillEffectLayerInformation.m 3 | // SFPSDWriter Mac OS X 4 | // 5 | // Created by Konstantin Erokhin on 15/06/14. 6 | // Copyright (c) 2014 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import "SFPSDSolidFillEffectLayerInformation.h" 10 | 11 | @implementation SFPSDSolidFillEffectLayerInformation 12 | 13 | @synthesize blendMode = _blendMode, color = _color, opacity = _opacity, enabled = _enabled; 14 | 15 | - (id)init 16 | { 17 | self = [super init]; 18 | if (self) 19 | { 20 | _blendMode = SFPSDLayerBlendModeNormal; 21 | 22 | CGFloat components[4] = {0.0,0.0,0.0,0.0}; 23 | _color = CGColorCreate(CGColorSpaceCreateDeviceRGB(), components); 24 | 25 | _opacity = 100; 26 | _enabled = NO; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)setOpacity:(long)opacity 32 | { 33 | if (opacity < 0) { 34 | opacity = 0; 35 | } 36 | else if (opacity > 100) { 37 | opacity = 100; 38 | } 39 | _opacity = opacity; 40 | } 41 | 42 | - (long)opacity255 43 | { 44 | return 2.55 * _opacity; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/SFPSDGroupClosingLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDGroupClosingLayer.h 3 | // SFPSDWriter 4 | // 5 | // Created by Konstantin Erokhin on 06/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | // Inspired by PSDWriter by Ben Gotow ( https://github.com/bengotow/PSDWriter ) 9 | // 10 | 11 | #import "SFPSDGroupLayer.h" 12 | #import "SFPSDGroupOpeningLayer.h" 13 | 14 | @interface SFPSDGroupClosingLayer : SFPSDGroupLayer 15 | 16 | /** 17 | * If this property is set - the information from the group opening layer will be copied 18 | * to the current layer before writing the extra layer information */ 19 | @property (nonatomic, strong) SFPSDGroupOpeningLayer *groupOpeningLayer; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/SFPSDGroupClosingLayer.m: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDGroupClosingLayer.m 3 | // SFPSDWriter 4 | // 5 | // Created by Konstantin Erokhin on 06/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | // Inspired by PSDWriter by Ben Gotow ( https://github.com/bengotow/PSDWriter ) 9 | // 10 | 11 | #import "SFPSDGroupClosingLayer.h" 12 | 13 | #import "NSMutableData+SFAppendValue.h" 14 | 15 | @implementation SFPSDGroupClosingLayer 16 | 17 | @synthesize groupOpeningLayer = _groupOpeningLayer; 18 | 19 | #pragma mark - Overrides of SFPSDLayer functions 20 | 21 | - (NSData *)extraLayerInformation 22 | { 23 | NSMutableData *extraDataStream = [[NSMutableData alloc] init]; 24 | 25 | if (nil != [self groupOpeningLayer]) { 26 | [self copyGroupInformationFrom:[self groupOpeningLayer]]; 27 | } 28 | 29 | [extraDataStream sfAppendValue:0 length:4]; // Layer mask / adjustment layer data. Size of the data: 36, 20, or 0. 30 | [extraDataStream sfAppendValue:0 length:4]; // Layer blending ranges data. Length of layer blending ranges data 31 | 32 | // Layer name: Pascal string, padded to a multiple of 4 bytes. 33 | [self writeNameOn:extraDataStream withPadding:4]; 34 | 35 | // Section divider setting (Photoshop 6.0) 36 | [extraDataStream sfAppendUTF8String:@"8BIM" length:4]; 37 | [extraDataStream sfAppendUTF8String:@"lsct" length:4]; 38 | [extraDataStream sfAppendValue:12 length:4]; // Section divider length 39 | 40 | if (self.isOpened) { 41 | [extraDataStream sfAppendValue:1 length:4]; // Type. 0 = any other type of layer, 1 = open "folder", 2 = closed "folder", 3 = bounding section divider, hidden in the UI 42 | } 43 | else { 44 | [extraDataStream sfAppendValue:2 length:4]; // Type. 0 = any other type of layer, 1 = open "folder", 2 = closed "folder", 3 = bounding section divider, hidden in the UI 45 | } 46 | 47 | [extraDataStream sfAppendUTF8String:@"8BIM" length:4]; 48 | [extraDataStream sfAppendUTF8String:SFPSDLayerBlendModePassThrough length:4]; // Blend mode: pass 49 | 50 | // Writing the Effects Layer containing information about Drop Shadow, Inner Shadow, Outer Glow, Inner Glow, Bevel, Solid Fill 51 | [self writeEffectsLayerOn:extraDataStream]; 52 | 53 | // Unicode layer name (Photoshop 5.0). Unicode string (4 bytes length + string). 54 | [self writeUnicodeNameOn:extraDataStream]; 55 | 56 | return extraDataStream; 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/SFPSDGroupLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDGroupLayer.h 3 | // SFPSDWriter 4 | // 5 | // Created by Konstantin Erokhin on 06/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SFPSDLayer.h" 12 | 13 | @interface SFPSDGroupLayer : SFPSDLayer 14 | 15 | /** If the group layer is shown opened or closed. Default is NO */ 16 | @property (nonatomic, assign) BOOL isOpened; 17 | 18 | /** Simple initializer. */ 19 | - (id)initWithName:(NSString *)name; 20 | 21 | /** Designed initializer. */ 22 | - (id)initWithName:(NSString *)name andOpacity:(float)opacity andIsOpened:(BOOL)isOpened; 23 | 24 | /** 25 | * Copies the Group layer information from another Group layer 26 | * Useful if you want to setup the information on the Closing Group Layer and don't remember 27 | * the information you've put in the Opening one */ 28 | - (void)copyGroupInformationFrom:(SFPSDGroupLayer *)layer; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/SFPSDGroupLayer.m: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDGroupLayer.m 3 | // SFPSDWriter 4 | // 5 | // Created by Konstantin Erokhin on 06/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | 9 | #import "SFPSDGroupLayer.h" 10 | 11 | #import "NSMutableData+SFAppendValue.h" 12 | 13 | @implementation SFPSDGroupLayer 14 | 15 | @synthesize isOpened = _isOpened; 16 | 17 | - (id)initWithName:(NSString *)name 18 | { 19 | return [self initWithName:name andOpacity:1.0 andIsOpened:NO]; 20 | } 21 | 22 | - (id)initWithName:(NSString *)name andOpacity:(float)opacity andIsOpened:(BOOL)isOpened 23 | { 24 | self = [super init]; 25 | if (!self) return nil; 26 | 27 | self.name = name; 28 | self.isOpened = isOpened; 29 | self.opacity = opacity; 30 | 31 | return self; 32 | } 33 | 34 | - (void)copyGroupInformationFrom:(SFPSDGroupLayer *)layer 35 | { 36 | // Copying later informations 37 | [self setName:layer.name]; 38 | [self setOpacity:layer.opacity]; 39 | [self setIsOpened:layer.isOpened]; 40 | 41 | // Copying Effect Layers 42 | [self setDropShadowEffectLayerInformation:layer.dropShadowEffectLayerInformation]; 43 | [self setInnerShadowEffectLayerInformation:layer.innerShadowEffectLayerInformation]; 44 | [self setOuterGlowEffectLayerInformation:layer.outerGlowEffectLayerInformation]; 45 | [self setInnerGlowEffectLayerInformation:layer.innerGlowEffectLayerInformation]; 46 | [self setBevelEffectLayerInformation:layer.bevelEffectLayerInformation]; 47 | [self setSolidFillEffectLayerInformation:layer.solidFillEffectLayerInformation]; 48 | } 49 | 50 | #pragma mark - Overrides of SFPSDLayer functions 51 | 52 | - (NSArray *)layerChannels 53 | { 54 | // Creating empty channels for the Group Layer with only compression formats 55 | NSMutableArray *layerChannels = [NSMutableArray array]; 56 | for (int channel = 0; channel < [self numberOfChannels]; channel++) { 57 | NSMutableData *channelData = [NSMutableData data]; 58 | // write channel compression format 59 | [channelData sfAppendValue:0 length:2]; 60 | // add completed channel data to channels array 61 | [layerChannels addObject:channelData]; 62 | } 63 | return layerChannels; 64 | } 65 | 66 | - (BOOL)hasValidSize 67 | { 68 | // The group layers has always valid size 69 | return YES; 70 | } 71 | 72 | @end -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/SFPSDGroupOpeningLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDGroupOpeningLayer.h 3 | // SFPSDWriter 4 | // 5 | // Created by Konstantin Erokhin on 06/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | // Inspired by PSDWriter by Ben Gotow ( https://github.com/bengotow/PSDWriter ) 9 | // 10 | 11 | #import "SFPSDGroupLayer.h" 12 | 13 | @interface SFPSDGroupOpeningLayer : SFPSDGroupLayer 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/SFPSDGroupOpeningLayer.m: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDGroupOpeningLayer.m 3 | // SFPSDWriter 4 | // 5 | // Created by Konstantin Erokhin on 06/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | // Inspired by PSDWriter by Ben Gotow ( https://github.com/bengotow/PSDWriter ) 9 | // 10 | 11 | #import "SFPSDGroupOpeningLayer.h" 12 | 13 | #import "NSMutableData+SFAppendValue.h" 14 | 15 | @implementation SFPSDGroupOpeningLayer 16 | 17 | #pragma mark - Overrides of SFPSDLayer functions 18 | 19 | - (NSData *)extraLayerInformation 20 | { 21 | NSMutableData *extraDataStream = [[NSMutableData alloc] init]; 22 | 23 | [extraDataStream sfAppendValue:0 length:4]; // Layer mask / adjustment layer data. Size of the data: 36, 20, or 0. 24 | [extraDataStream sfAppendValue:0 length:4]; // Layer blending ranges data. Length of layer blending ranges data 25 | 26 | // Temporally hanging the name to the default PS group's ending marker name 27 | NSString *layerName = self.name; 28 | [self setName:@""]; 29 | 30 | // Layer name: Pascal string, padded to a multiple of 4 bytes. 31 | [self writeNameOn:extraDataStream withPadding:4]; 32 | 33 | // Section divider setting (Photoshop 6.0) 34 | [extraDataStream sfAppendUTF8String:@"8BIM" length:4]; 35 | [extraDataStream sfAppendUTF8String:@"lsct" length:4]; 36 | [extraDataStream sfAppendValue:4 length:4]; // Section divider length 37 | [extraDataStream sfAppendValue:3 length:4]; // Type. 0 = any other type of layer, 1 = open "folder", 2 = closed "folder", 3 = bounding section divider, hidden in the UI 38 | 39 | // Unicode layer name (Photoshop 5.0). Unicode string (4 bytes length + string). 40 | [self writeUnicodeNameOn:extraDataStream]; 41 | 42 | // Restoring the layer name 43 | [self setName:layerName]; 44 | 45 | return extraDataStream; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Library/SFPSDWriter/Layer Classes/SFPSDLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDLayer.h 3 | // SFPSDWriter 4 | // 5 | // Created by Konstantin Erokhin on 06/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | // Inspired by PSDWriter by Ben Gotow ( https://github.com/bengotow/PSDWriter ) 9 | // 10 | 11 | #import 12 | 13 | #if TARGET_OS_IPHONE 14 | #import 15 | #endif 16 | 17 | #import "SFPSDLayerBlendModes.h" 18 | #import "SFPSDEffectsLayerEffectSignatures.h" 19 | 20 | #import "SFPSDEffectLayerInformations.h" 21 | 22 | @interface SFPSDLayer : NSObject 23 | { 24 | } 25 | 26 | /** The size of the document the layer will be insert into. */ 27 | @property (nonatomic, assign) CGSize documentSize; 28 | 29 | /** The name of the layer. */ 30 | @property (nonatomic, strong) NSString *name; 31 | 32 | /** The image reference */ 33 | @property (nonatomic, assign) CGImageRef image; 34 | 35 | /** 36 | * The image data in RGBA format. 37 | * 38 | * The data is kept as property because of the massive use in the PSD generation phase. The 39 | * data is created on first usage and niled every time the image changes. */ 40 | @property (nonatomic, strong) NSData *visibleImageData; 41 | 42 | //@property (nonatomic, assign) CGRect imageRegion; 43 | 44 | /** The opacity of the layer between 0 and 1. */ 45 | @property (nonatomic, assign) float opacity; 46 | 47 | /** Layer offset */ 48 | @property (nonatomic, assign) CGPoint offset; 49 | 50 | /** Number of channels of the layer. Defaults to 4. */ 51 | @property (nonatomic, assign) NSInteger numberOfChannels; 52 | 53 | /** 54 | * Allows you to automatically vertically flip the image data when it's being 55 | * written to PSD. This is important if the source images are coming from OpenGL or 56 | * another drawing system with an inverted coordinate system. */ 57 | @property (nonatomic, assign) BOOL shouldFlipLayerData; 58 | 59 | /** 60 | * Allows you to automatically unpremultiply the image data. Premultiplication is 61 | * a process by which the R,G, and B values are multiplied by the alpha. Setting this 62 | * to YES will cause RGB to be divided by A. You'll know you need to do this if the 63 | * image comes out darker than you expect. */ 64 | @property (nonatomic, assign) BOOL shouldUnpremultiplyLayerData; 65 | 66 | /** Layer blend mode. */ 67 | @property (nonatomic, strong) NSString *blendMode; 68 | 69 | #pragma mark - Effects Layer Informations 70 | 71 | /** Effects Layer information for the Drop Shafow Effect 72 | * Can be found in the "Layer -> Layer Style" menu in Photoshop */ 73 | @property (nonatomic, strong) SFPSDDropShadowEffectLayerInformation *dropShadowEffectLayerInformation; 74 | 75 | /** Effects Layer information for the Inner Shafow Effect 76 | * Can be found in the "Layer -> Layer Style" menu in Photoshop */ 77 | @property (nonatomic, assign) SFPSDInnerShadowEffectLayerInformation *innerShadowEffectLayerInformation; 78 | 79 | /** Effects Layer information for the Outer Glow Effect 80 | * Can be found in the "Layer -> Layer Style" menu in Photoshop */ 81 | @property (nonatomic, assign) SFPSDOuterGlowEffectLayerInformation *outerGlowEffectLayerInformation; 82 | 83 | /** Effects Layer information for the Inner Glow Effect 84 | * Can be found in the "Layer -> Layer Style" menu in Photoshop */ 85 | @property (nonatomic, assign) SFPSDInnerGlowEffectLayerInformation *innerGlowEffectLayerInformation; 86 | 87 | /** Effects Layer information for the Bevel Effect 88 | * Can be found in the "Layer -> Layer Style" menu in Photoshop */ 89 | @property (nonatomic, assign) SFPSDBevelEffectLayerInformation *bevelEffectLayerInformation; 90 | 91 | /** Effects Layer information for the Solid Fill Effect 92 | * Can be found in the "Layer -> Layer Style" menu in Photoshop */ 93 | @property (nonatomic, assign) SFPSDSolidFillEffectLayerInformation *solidFillEffectLayerInformation; 94 | 95 | #pragma mark - Initializers 96 | 97 | /** Designed initializer. */ 98 | - (id)initWithNumberOfChannels:(int)numberOfChannels andOpacity:(float)opacity andShouldFlipLayerData:(BOOL)shouldFlipLayerData andShouldUnpremultiplyLayerData:(BOOL)shouldUnpremultiplyLayerData andBlendMode:(NSString *)blendMode; 99 | 100 | /** 101 | * Returns a Boolean value that indicates whether the layer has some printable content inside the document bounds. 102 | * @return YES if the layer can be printed inside the document bounds. NO if the layer is entirely outside the document bounds. */ 103 | - (BOOL)hasValidSize; 104 | 105 | /** The part of the image to use in the layer depending on position. If some part of the layer is out of bounds the image is cropped. */ 106 | - (CGRect)imageCropRegion; 107 | 108 | /** The portion of the document occupied by the image. */ 109 | - (CGRect)imageInDocumentRegion; 110 | 111 | /** 112 | * The CGImage cropped usign the CGRect provided by -imageCropRegion. */ 113 | - (CGImageRef)croppedImage; 114 | 115 | /** 116 | * Writes the Layer Information Section inside the mutable data (the first part of the "Layer info" 117 | * section of the "Layer and mask information section") 118 | * 119 | * Adobe documentation: Information about each layer. See Layer records describes the structure of 120 | * this information for each layer. */ 121 | - (void)writeLayerInformationOn:(NSMutableData *)layerInformation; 122 | 123 | /** 124 | * Writes the "Channel Image Data" inside the mutable data (the second part of the "Layer info" 125 | * section of the "Layer and mask information section") 126 | * 127 | * Adobe documentation: Channel image data. Contains one or more image data records (see See Channel 128 | * image data for structure) for each layer. The layers are in the same order as in the layer 129 | * information (previous row of this table). */ 130 | - (void)writeLayerChannelsOn:(NSMutableData *)layerInformation; 131 | 132 | @end 133 | 134 | @interface SFPSDLayer (Protected) 135 | 136 | /** Returns an array of the channels composing the layer. */ 137 | - (NSArray *)layerChannels; 138 | 139 | /** Writes the name on data. Tipically used in the "extra data field". */ 140 | - (void)writeNameOn:(NSMutableData *)data withPadding:(int)padding; 141 | 142 | /** Writes the Effects Layer containing information about Drop Shadow, Inner Shadow, 143 | * Outer Glow, Inner Glow, Bevel, Solid Fill. Tipically used in the "extra data field". */ 144 | - (void)writeEffectsLayerOn:(NSMutableData *)data; 145 | 146 | /** Writes the unicode name on data. Tipically used in the "extra data field". */ 147 | - (void)writeUnicodeNameOn:(NSMutableData *)data; 148 | 149 | /** Extra layer information data. Has to be overridden in the extended classes (i.e. in the 150 | * PSDGroupOpeningLayer and PSDGroupClosingLayer). */ 151 | - (NSData *)extraLayerInformation; 152 | 153 | @end 154 | 155 | /** 156 | * A convenience function for getting RGBA NSData from a CGImageRef. 157 | */ 158 | NSData *CGImageGetData(CGImageRef image, CGRect region); -------------------------------------------------------------------------------- /Library/SFPSDWriter/SFPSDWriter.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFPSDWriter.h 3 | // SFPSDWriter 4 | // 5 | // Created by Konstantin Erokhin on 06/06/13. 6 | // Copyright (c) 2013 Shiny Frog. All rights reserved. 7 | // 8 | // Inspired by PSDWriter by Ben Gotow ( https://github.com/bengotow/PSDWriter ) 9 | // 10 | 11 | #import 12 | #if TARGET_OS_IPHONE 13 | #import 14 | #endif 15 | 16 | #import "SFPSDLayer.h" 17 | #import "SFPSDGroupOpeningLayer.h" 18 | #import "SFPSDGroupClosingLayer.h" 19 | 20 | struct SFPSDResolution { 21 | float hResolution; 22 | float vResolution; 23 | }; 24 | typedef struct SFPSDResolution SFPSDResolution; 25 | 26 | enum SFPSDResolutionUnit { 27 | SFPSDResolutionUnitPPI = 1, 28 | SFPSDResolutionUnitPPC = 2 29 | }; 30 | typedef enum SFPSDResolutionUnit SFPSDResolutionUnit; 31 | 32 | enum SFPSDColorProfile { 33 | SFPSDNoColorProfile, // No color profile (Don't Color Manage This Document) 34 | SFPSDGenericRGBColorProfile, // Generic RGB 35 | SFPSDSRGBColorProfile, // sRGB IEC61966-2.1 36 | SFPSDAdobeRGB1998ColorProfile // Adobe RGB (1998) 37 | }; 38 | typedef enum SFPSDColorProfile SFPSDColorProfile; 39 | 40 | @interface SFPSDWriter : NSObject 41 | { 42 | } 43 | 44 | /** Context used to hold the flattened image for the PSD preview */ 45 | @property (nonatomic, assign) CGContextRef flattenedContext; 46 | 47 | /** 48 | * The PSDLayer objects with layer data, names, etc... Note that when you call 49 | * createPSDData, this array is slowly emptied - the PSDWriter removes the individual layers 50 | * from memory as it builds the PSD file. */ 51 | @property (nonatomic, strong) NSMutableArray *layers; 52 | 53 | /** The size of the PSD you're exporting. */ 54 | @property (nonatomic, assign) CGSize documentSize; 55 | 56 | /** 57 | * The pixel per inch property of the resulting document. 58 | * It is a SFPSDResolution because the document can have different vertical and horizontal resolutions */ 59 | @property (nonatomic, assign) SFPSDResolution documentResolution; 60 | 61 | /** The unit of the document resolution. */ 62 | @property (nonatomic, assign) SFPSDResolutionUnit documentResolutionUnit; 63 | 64 | /** The embedded color profile of the document. */ 65 | @property (nonatomic, assign) SFPSDColorProfile colorProfile; 66 | 67 | /** 68 | * The number of channels in each layer. Defaults to 4, unless layers 69 | * are not transparent. This is the global */ 70 | @property (nonatomic, assign) BOOL hasTransparentLayers; 71 | 72 | /** Optional. The RGBA data for a flattened "preview" of the PSD. */ 73 | @property (nonatomic, strong) NSData * flattenedData; 74 | 75 | /** 76 | * Initializes a new PSDWriter for creating a PSD document with the specified size. 77 | * @param size The document size. */ 78 | - (id)initWithDocumentSize:(CGSize)documentSize; 79 | 80 | /** 81 | * Initializes a new PSDWriter for creating a PSD document with the specified size and resolution value. 82 | * @param documentSize The document size. 83 | * @param resolution The resolution value of the document. */ 84 | - (id)initWithDocumentSize:(CGSize)documentSize andResolution:(float)resolution andResolutionUnit:(SFPSDResolutionUnit)resolutionUnit; 85 | 86 | /** 87 | * Designed initializer. 88 | * 89 | * @param documentSize document size. 90 | * @param resolution The resolution value of the document. 91 | * @param resolutionUnit The unit of the document resolution. 92 | * @param hasTransparentLayers tells if the layer has the alpha channel. 93 | * @param layers Initial layers. */ 94 | - (id)initWithDocumentSize:(CGSize)documentSize andResolution:(float)resolution andResolutionUnit:(SFPSDResolutionUnit)resolutionUnit andHasTransparentLayers:(BOOL)hasTransparentLayers andLayers:(NSArray *)layers; 95 | 96 | /** 97 | * Adds a new layer to the PSD image with a name. The opacity of the layer will be 1 and no offset will be applied. 98 | * 99 | * @param image The image to be added. Does not need to be the same size as the document. If the image is larger than the document it will be cropped in the final result. 100 | * @param name The name you'd like to give the layer. 101 | * 102 | * @return The newly created layer in order to customize it after the creation. */ 103 | - (SFPSDLayer *)addLayerWithCGImage:(CGImageRef)image andName:(NSString*)name; 104 | 105 | /** 106 | * Adds a new layer to the PSD image with the provided properties. 107 | * 108 | * If you are using NSImages and not CGImages, use the following code to convert to CGImageRefs: 109 | * 110 | * NSImage* yourImage; 111 | * CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)[yourImage TIFFRepresentation], NULL); 112 | * CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, 0, NULL); 113 | * 114 | * If you prefer, you can setup PSDLayers by yourself 115 | * and put them in the PSDWriter.layers array, but this method automatically creates the flattenedData, 116 | * an image that is a flattened preview of the layered PSD. If you populate the layer objects yourself, 117 | * you need to provide the flattened image data yourself. 118 | * 119 | * Note: Having layers partially off the edge of the canvas is not currently supported. 120 | * 121 | * @param image The image to be added. Does not need to be the same size as the document. If the image is larger than the document it will be cropped. 122 | * @param name The name you'd like to give the layer. 123 | * @param opacity The opacity of the layer, from [0-1] 124 | * @param offset The offset of the layer within the document. Use this to position layers within the PSD. 125 | * 126 | * @return The newly created layer in order to customize it after the creation. */ 127 | - (SFPSDLayer *)addLayerWithCGImage:(CGImageRef)image andName:(NSString*)name andOpacity:(float)opacity andOffset:(CGPoint)offset; 128 | 129 | /** 130 | * Opens a new PSD group. 131 | * 132 | * The group will contain all the layers and groups added to the PSDWriter's instance before the corresponding -closeCurrentGroupLayer is called 133 | * 134 | * @param name The name of the group 135 | * 136 | * @return The newly created Group in order to customize it after the creation. */ 137 | - (SFPSDGroupOpeningLayer *)openGroupLayerWithName:(NSString *)name; 138 | 139 | /** 140 | * Opens a new PSD group. 141 | * 142 | * The group will contain all the layers and groups added to the PSDWriter's instance before the corresponding -closeCurrentGroupLayer is called 143 | * 144 | * @param name The name of the group 145 | * @param opacity The opacity of the group 146 | * @param isOpened If the group should be opened inside the PSD 147 | * 148 | * @return The newly created Group in order to customize it after the creation. */ 149 | - (SFPSDGroupOpeningLayer *)openGroupLayerWithName:(NSString *)name andOpacity:(float)opacity andIsOpened:(BOOL)isOpened; 150 | 151 | /** Closes the corresponding opened PSD group without returning errors. The function will simply return nil if there is no opened group to close. */ 152 | - (SFPSDGroupClosingLayer *)closeCurrentGroupLayer; 153 | 154 | /** 155 | * Closes the corresponding opened PSD group. 156 | * 157 | * The layer will have the name and other data of the SFPSDGroupOpeningLayer that it is closing 158 | * 159 | * @return The newly created group layer in order to customize it after the creation. */ 160 | - (SFPSDGroupClosingLayer *)closeCurrentGroupLayerWithError:(NSError * __autoreleasing *)error; 161 | 162 | /** The number of channels of the PSD document. If it has transparencies - 4, else 3. */ 163 | - (int)numberOfChannels; 164 | 165 | /** An array with only visible layers inside the document bounds. */ 166 | - (NSArray *)visibleLayers; 167 | 168 | /** Deprecated function. Use -createPSDDataWithError: instead */ 169 | - (NSData *)createPSDData; 170 | 171 | /** 172 | * Generates an NSData object representing a PSD image with the width and height specified by documentSize 173 | * and the contents specified by the layers array. Note that this function can be (and really should be) 174 | * called on a separate thread. 175 | * 176 | * @return PSD data. This data has to be written on a file. */ 177 | - (NSData *)createPSDDataWithError:(NSError * __autoreleasing *)error; 178 | 179 | @end 180 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SFPSDWriter 2 | 3 | SFPSDWriter is an Objective-C library for writing PSD files. Here at Shiny Frog we needed a way to write **multilayer** **PSDs** with **groups** and this library is the result after days of headaches. 4 | 5 | It features: 6 | 7 | * Multilayer PSD creation 8 | * Grouping of layers 9 | * Unicode layer name support 10 | * Some layer configurations (like the blend mode of the layer) 11 | * Basic Effects for Layers and Groups: Drop Shadow, Inner Shadow, Outer Glow, Inner Glow, Bevel, Solid Fill 12 | * ARC (Automatic Reference Counting) 13 | 14 | What SFPSDWriter **NOT** features: 15 | 16 | * Ability to read PSD files 17 | 18 | ## Usage 19 | 20 | ### In two words: 21 | 22 | * Create an instance a SFPSDWriter object 23 | * Add how many layers you want 24 | * Eventually modify the layer's characteristics 25 | * Add some layer effects, if you want to 26 | * Retrieve the NSData generated by the SFPSDWriter and store it wherever you want 27 | 28 | ### Of course, some code: 29 | 30 | #### Mac OS X 31 | 32 | ```Objective-C 33 | // The images we want to insert in the PSD 34 | NSImage *firstImage = [NSImage imageNamed:@"firstImage"]; 35 | NSImage *secondImage = [NSImage imageNamed:@"secondImage"]; 36 | 37 | // SFPSDWriter instance 38 | SFPSDWriter *psdWriter = [[SFPSDWriter alloc] initWithDocumentSize:NSSizeToCGSize(firstImage.size) andResolution:300.0 andResolutionUnit:SFPSDResolutionUnitPPI]; 39 | 40 | // We want all our layers to be included in a group... 41 | SFPSDGroupOpeningLayer *firstGroup = [psdWriter openGroupLayerWithName:@"We ♥ groups!"]; 42 | 43 | // ... and the group should be open at file opening 44 | [firstGroup setIsOpened:YES]; 45 | 46 | // Adding the first image layer 47 | [psdWriter addLayerWithCGImage:[[[firstImage representations] objectAtIndex:0] CGImage] 48 | andName:@"First Layer" 49 | andOpacity:1 50 | andOffset:NSMakePoint(0, 0)]; 51 | 52 | // I mean, we really love groups 53 | // This time we don't need to change group's attributes so we don't store the reference 54 | [psdWriter openGroupLayerWithName:@"You'll have to open me!"]; 55 | 56 | // The second image will be in the second group, offsetted by (116px, 66px), semi-transparent... 57 | SFPSDLayer *secondLayer = [psdWriter addLayerWithCGImage:[[[secondImage representations] objectAtIndex:0] CGImage] 58 | andName:@"Second Layer" 59 | andOpacity:0.5 60 | andOffset:NSMakePoint(116, 66)]; 61 | 62 | // ... and with "Darken" blend mode 63 | [secondLayer setBlendMode:SFPSDLayerBlendModeDarken]; 64 | 65 | // We'll prepare the Drop Shadow Effect Layer information 66 | SFPSDDropShadowEffectLayerInformation *dropShadowInformation = [[SFPSDDropShadowEffectLayerInformation alloc] init]; 67 | dropShadowInformation.enabled = YES; 68 | dropShadowInformation.size = 100; 69 | dropShadowInformation.angle = 90; 70 | dropShadowInformation.distance = 30; 71 | dropShadowInformation.color = [[NSColor redColor] CGColor]; 72 | dropShadowInformation.blendMode = SFPSDLayerBlendModeNormal; 73 | dropShadowInformation.useGlobalLight = NO; 74 | dropShadowInformation.opacity = 100; 75 | 76 | // We'll set the Drop Sahdow on the second layer (we can add it to the SFPSDGroupOpeningLayer too) 77 | [secondLayer setDropShadowEffectLayerInformation:dropShadowInformation]; 78 | 79 | // Other available Effect Layers are: 80 | // - Inner Shadow (SFPSDInnerShadowEffectLayerInformation) 81 | // - Outer Glow (SFPSDOuterGlowEffectLayerInformation) 82 | // - Inner Glow (SFPSDInnerGlowEffectLayerInformation) 83 | // - Bevel (SFPSDBevelEffectLayerInformation) 84 | // - Solid Fill (SFPSDSolidFillEffectLayerInformation) 85 | 86 | // We have to close every group we've opened 87 | [psdWriter closeCurrentGroupLayer]; // second group 88 | [psdWriter closeCurrentGroupLayer]; // first group 89 | 90 | // We can change the embedded color profile of the document (for example with an "sRGB IEC61966-2.1") 91 | [psdWriter setColorProfile:SFPSDSRGBColorProfile]; 92 | 93 | // We'll write our test file to the Desktop 94 | NSString *basePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Desktop"]; 95 | NSString *fullFilePath = [basePath stringByAppendingPathComponent:@"SFPSDWriter Test File.psd"]; 96 | 97 | // Retrieving the PSD data 98 | NSError *error = nil; 99 | NSData * psd = [psdWriter createPSDDataWithError:&error]; 100 | 101 | // Checking for errors 102 | if (nil != error) { 103 | NSLog(@"There was an error writing the PSD: %@", [error description]); 104 | return; 105 | } 106 | 107 | // Writing the data on disk 108 | [psd writeToFile:fullFilePath atomically:NO]; 109 | 110 | // Opening the newly created file! :) 111 | [[NSWorkspace sharedWorkspace] openFile:fullFilePath]; 112 | ``` 113 | 114 | #### iOS 115 | 116 | ```Objective-C 117 | // The images we want to insert in the PSD 118 | UIImage *firstImage = [UIImage imageNamed:@"firstImage"]; 119 | UIImage *secondImage = [UIImage imageNamed:@"secondImage"]; 120 | 121 | // SFPSDWriter instance 122 | SFPSDWriter *psdWriter = [[SFPSDWriter alloc] initWithDocumentSize:firstImage.size andResolution:300.0 andResolutionUnit:SFPSDResolutionUnitPPI]; 123 | 124 | // We want all our layers to be included in a group... 125 | SFPSDGroupOpeningLayer *firstGroup = [psdWriter openGroupLayerWithName:@"We ♥ groups!"]; 126 | 127 | // ... and the group should be open at file opening 128 | [firstGroup setIsOpened:YES]; 129 | 130 | // Adding the first image layer 131 | [psdWriter addLayerWithCGImage:[firstImage CGImage] 132 | andName:@"First Layer" 133 | andOpacity:1 134 | andOffset:CGPointMake(0, 0)]; 135 | 136 | // I mean, we really love groups 137 | // This time we don't need to change group's attributes so we don't store the reference 138 | [psdWriter openGroupLayerWithName:@"You'll have to open me!"]; 139 | 140 | // The second image will be in the second group, offsetted by (116px, 66px), semi-transparent... 141 | SFPSDLayer *secondLayer = [psdWriter addLayerWithCGImage:[secondImage CGImage] 142 | andName:@"Second Layer" 143 | andOpacity:0.5 144 | andOffset:CGPointMake(116, 66)]; 145 | 146 | // ... and with "Darken" blend mode 147 | [secondLayer setBlendMode:SFPSDLayerBlendModeDarken]; 148 | 149 | // We'll prepare the Drop Shadow Effect Layer information 150 | SFPSDDropShadowEffectLayerInformation *dropShadowInformation = [[SFPSDDropShadowEffectLayerInformation alloc] init]; 151 | dropShadowInformation.enabled = YES; 152 | dropShadowInformation.size = 100; 153 | dropShadowInformation.angle = 90; 154 | dropShadowInformation.distance = 30; 155 | dropShadowInformation.color = [[UIColor redColor] CGColor]; 156 | dropShadowInformation.blendMode = SFPSDLayerBlendModeNormal; 157 | dropShadowInformation.useGlobalLight = NO; 158 | dropShadowInformation.opacity = 100; 159 | 160 | // We'll set the Drop Sahdow on the second layer (we can add it to the SFPSDGroupOpeningLayer too) 161 | [secondLayer setDropShadowEffectLayerInformation:dropShadowInformation]; 162 | 163 | // Other available Effect Layers are: 164 | // - Inner Shadow (SFPSDInnerShadowEffectLayerInformation) 165 | // - Outer Glow (SFPSDOuterGlowEffectLayerInformation) 166 | // - Inner Glow (SFPSDInnerGlowEffectLayerInformation) 167 | // - Bevel (SFPSDBevelEffectLayerInformation) 168 | // - Solid Fill (SFPSDSolidFillEffectLayerInformation) 169 | 170 | // We have to close every group we've opened 171 | [psdWriter closeCurrentGroupLayer]; // second group 172 | [psdWriter closeCurrentGroupLayer]; // first group 173 | 174 | // We can change the embedded color profile of the document (for example with an "sRGB IEC61966-2.1") 175 | [psdWriter setColorProfile:SFPSDSRGBColorProfile]; 176 | 177 | // We'll write our test file into the documents folder of the application 178 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 179 | NSString *documentsDirectory = [paths objectAtIndex:0]; 180 | NSString *fullFilePath = [documentsDirectory stringByAppendingPathComponent:@"SFPSDWriter Test File.psd"]; 181 | 182 | // Retrieving the PSD data 183 | NSError *error = nil; 184 | NSData * psd = [psdWriter createPSDDataWithError:&error]; 185 | 186 | // Checking for errors 187 | if (nil != error) { 188 | NSLog(@"There was an error writing the PSD: %@", [error description]); 189 | return; 190 | } 191 | 192 | // Writing the data on disk 193 | // When using the simulator we can find the file in 194 | // /Users//Library/Application\ Support/iPhone\ Simulator//Applications//Documents 195 | [psd writeToFile:fullFilePath atomically:NO]; 196 | ``` 197 | 198 | ## Example Projects 199 | 200 | The example projects are a copy and paste of the code in the [Usage](https://github.com/shinyfrog/SFPSDWriter#usage) section in: 201 | 202 | ```Objective-C 203 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification // Mac OS X 204 | ``` 205 | 206 | and 207 | 208 | ```Objective-C 209 | - (void)applicationDidBecomeActive:(UIApplication *)application // iOS 210 | ``` 211 | 212 | There is also a debug project used to stress test the library. You can find it in *[Example Projects/SFPSDWriter Stress Tester](https://github.com/shinyfrog/SFPSDWriter/tree/master/Example%20Projects/SFPSDWriter%20Stress%20Tester)*. 213 | 214 | ## Status 215 | 216 | The library is functionally complete for our needs so there is no planning on working on it. Obviously there will be bugfixes or speedups if we'll found some while using it. 217 | 218 | There is no plan to make this library able to read PSDs. Or let's make it this way: there is a concrete plan to **not** make the library read PSD files. 219 | 220 | At this point I'd like to invite you to read this [famous comment](https://code.google.com/p/xee/source/browse/XeePhotoshopLoader.m#108) to let you understand what does it mean to work with PSD files. Have to admit that I found that comment motivational but I'm a pervert. Don't play with PSD files if you can. :) 221 | 222 | ## Contributing 223 | 224 | We will happily evaluate the possibility to accept pull requests so if you have suggestions - you are welcome to let us know. 225 | 226 | ## Acknowledgments 227 | 228 | This library gets inspiration from [Ben Gotow](https://github.com/bengotow)'s [PSDWriter](https://github.com/bengotow/PSDWriter). It was reorganized a bit in the structure to depute the writing of the informations and the channels to the layers (and adding something here and there). 229 | 230 | This library would be not possible without some pro tips of [Gus Mueller](https://github.com/ccgus) ([@ccgus](https://twitter.com/ccgus)) about the misterious behaviour of PSD groups! 231 | -------------------------------------------------------------------------------- /SFPSDWriter.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "SFPSDWriter" 4 | s.version = "0.3.1" 5 | s.summary = "A simple Objective C (Mac and iOS) writer for .psd files with multiple layers and groups." 6 | 7 | s.description = <<-DESC 8 | SFPSDWriter is an Objective-C library for writing PSD files. Here at Shiny Frog we needed a way to write **multilayer** **PSDs** with **groups** and this library is the result after days of headaches. 9 | 10 | It features: 11 | 12 | * Multilayer PSD creation 13 | * Grouping of layers 14 | * Unicode layer name support 15 | * Some layer configurations (like the blend mode of the layer) 16 | * ARC (Automatic Reference Counting) 17 | 18 | What SFPSDWriter **NOT** features: 19 | 20 | * Ability to read PSD files 21 | DESC 22 | 23 | s.homepage = "https://github.com/shinyfrog/SFPSDWriter/" 24 | 25 | s.license = { :type => 'BSD' } 26 | 27 | s.author = { "Shiny Frog" => "shinyfrog@shinyfrog.net" } 28 | 29 | s.source = { :git => "https://github.com/shinyfrog/SFPSDWriter.git", :tag => s.version.to_s } 30 | 31 | s.platform = :ios, :osx 32 | 33 | s.ios.deployment_target = "7.0" 34 | s.osx.deployment_target = "10.8" 35 | 36 | s.source_files = "Library/SFPSDWriter/**/*.{h,m}" 37 | 38 | s.requires_arc = true 39 | 40 | 41 | end 42 | --------------------------------------------------------------------------------