Skip to content

Commit 5038c71

Browse files
authored
Merge pull request #29 from SDWebImage/update_vector_resize_behavior
Update the calculation of bitmap image based on more complicated rules for most use cases
2 parents 7251c34 + 86393a6 commit 5038c71

File tree

2 files changed

+58
-18
lines changed

2 files changed

+58
-18
lines changed

README.md

+13
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,19 @@ In most cases, vector SVG is preferred. But however, sometimes you may want the
124124

125125
By default it use the SVG viewBox size. You can also specify a desired size during image loading using `.imageThumbnailPixelSize` context option. And you can specify whether or not to keep aspect ratio during scale using `.imagePreserveAspectRatio` context option.
126126

127+
Note: When using `imageThumbnailPixelSize`, pass 0 for width or height will remove the limit of this length. For example, given a SVG image which original size is `(40,50)`:
128+
129+
| preserve aspect ratio | width | height | effect |
130+
| --- | --- | --- | --- |
131+
| true | 50 | 50 | (40,50) |
132+
| true | 0 | 100 | (80,100) |
133+
| true | 20 | 0 | (20,25) |
134+
| true | 0 | 0 | (40,50) |
135+
| false | 50 | 50 | (50,50) |
136+
| false | 0 | 100 | (40,100) |
137+
| false | 20 | 0 | (20,50) |
138+
| false | 0 | 0 | (40,50) |
139+
127140
Note: Once you pass the `imageThumbnailPixelSize`, we will always generate the bitmap representation. If you do want the vector format, do not pass them, let `UIImageView` to dynamically stretch the SVG.
128141

129142
+ Objective-C

SDWebImageSVGCoder/Classes/SDImageSVGCoder.m

+45-18
Original file line numberDiff line numberDiff line change
@@ -192,28 +192,55 @@ - (UIImage *)createBitmapSVGWithData:(nonnull NSData *)data targetSize:(CGSize)t
192192
}
193193

194194
CGSize size = SDCGSVGDocumentGetCanvasSize(document);
195-
CGRect rect = CGRectMake(0, 0, size.width, size.height);
196-
CGRect targetRect = rect;
197-
if (!CGSizeEqualToSize(targetSize, CGSizeZero)) {
198-
targetRect = CGRectMake(0, 0, targetSize.width, targetSize.height);
195+
// Invalid size
196+
if (size.width == 0 || size.height == 0) {
197+
return nil;
199198
}
200199

201-
CGFloat xRatio = targetRect.size.width / rect.size.width;
202-
CGFloat yRatio = targetRect.size.height / rect.size.height;
203-
204-
// If we specify only one length of the size (width or height) we want to keep the ratio for that length
205-
if (preserveAspectRatio) {
206-
if (xRatio <= 0) {
207-
xRatio = yRatio;
208-
targetRect.size = CGSizeMake(rect.size.width * xRatio, targetSize.height);
209-
} else if (yRatio <= 0) {
210-
yRatio = xRatio;
211-
targetRect.size = CGSizeMake(targetSize.width, rect.size.height * yRatio);
200+
CGFloat xScale;
201+
CGFloat yScale;
202+
// Calculation for actual target size, see rules in documentation
203+
if (targetSize.width <= 0 && targetSize.height <= 0) {
204+
// Both width and height is 0, use original size
205+
targetSize.width = size.width;
206+
targetSize.height = size.height;
207+
xScale = 1;
208+
yScale = 1;
209+
} else {
210+
CGFloat xRatio = targetSize.width / size.width;
211+
CGFloat yRatio = targetSize.height / size.height;
212+
if (preserveAspectRatio) {
213+
// If we specify only one length of the size (width or height) we want to keep the ratio for that length
214+
if (targetSize.width <= 0) {
215+
yScale = yRatio;
216+
xScale = yRatio;
217+
targetSize.width = size.width * yRatio;
218+
} else if (targetSize.height <= 0) {
219+
xScale = xRatio;
220+
yScale = xRatio;
221+
targetSize.height = size.height * xRatio;
222+
} else {
223+
xScale = MIN(xRatio, yRatio);
224+
yScale = MIN(xRatio, yRatio);
225+
}
226+
} else {
227+
// If we specify only one length of the size but don't keep the ratio, use original size
228+
if (targetSize.width <= 0) {
229+
targetSize.width = size.width;
230+
yScale = yRatio;
231+
xScale = 1;
232+
} else if (targetSize.height <= 0) {
233+
xScale = xRatio;
234+
yScale = 1;
235+
targetSize.height = size.height;
236+
} else {
237+
xScale = xRatio;
238+
yScale = yRatio;
239+
}
212240
}
213241
}
214-
215-
CGFloat xScale = preserveAspectRatio ? MIN(xRatio, yRatio) : xRatio;
216-
CGFloat yScale = preserveAspectRatio ? MIN(xRatio, yRatio) : yRatio;
242+
CGRect rect = CGRectMake(0, 0, size.width, size.height);
243+
CGRect targetRect = CGRectMake(0, 0, targetSize.width, targetSize.height);
217244

218245
CGAffineTransform scaleTransform = CGAffineTransformMakeScale(xScale, yScale);
219246
CGAffineTransform transform = CGAffineTransformIdentity;

0 commit comments

Comments
 (0)