Combine more than one image to get a single image - image

I've to capture the contents of a UIView. There are plenty of methods to capture contents.The problem is,, if the size of the view becomes too big, the app crashes as it takes huge amount of memory.So is there any possibility to merge the raw image data (performing byte-by-byte operation) in a single file and make image from that??

`enter code here`Merging two images to create one single image file
Suppose we have two images with name file1.png and file2.png The code below merges two images.
#implementation LandscapeImage
- (void) createLandscapeImages
{
CGSize offScreenSize = CGSizeMake(2048, 1380);
UIGraphicsBeginImageContext(offScreenSize);
//Fetch First image and draw in rect
UIImage* imageLeft = [UIImage imageNamed:#"file1.png"];
CGRect rect = CGRectMake(0, 0, 1024, 1380);
[imageLeft drawInRect:rect];
[imageLeft release];
//Fetch second image and draw in rect
UIImage* imageRight = [UIImage imageNamed:#"file2.jpg"];
rect.origin.x += 1024;
[imageRight drawInRect:rect];
[imageRight release];
UIImage* imagez = UIGraphicsGetImageFromCurrentImageContext();// it will returns an image based on the contents of the current bitmap-based graphics context.
if (imageLeft && imageRight)
{
//Write code for save imagez in local cache
}
UIGraphicsEndImageContext();
}
#end

Related

Incorrect Histogram from CIAreaHistogram / CIHistogramDisplayFilter

I have a function that generates a CIImage* of a histogram, given a CGImageRef being passed in to the routine.
I get a histogram image back but the left side of the histogram appears to be compressed and the right side appears to be stretched out. I am wondering if I need to apply a CTM or should the code just return the proper image.
Here is the function:
- (CIImage*)histogramFromCGImage:(CGImageRef)image
{
CIImage *inputImage = [[CIImage alloc] initWithCGImage:image];
CIVector *inputExtent = [CIVector vectorWithCGRect:inputImage.extent];
NSNumber *inputCount = [NSNumber numberWithInteger:256];
NSNumber *inputScale = [NSNumber numberWithInteger:25];
CIImage *histogramOutputImage = [inputImage imageByApplyingFilter:#"CIAreaHistogram"
withInputParameters:#{
#"inputExtent" : inputExtent,
#"inputCount" : inputCount,
#"inputScale" : inputScale}
];
CIImage *outHistogramImage = [histogramOutputImage imageByApplyingFilter:#"CIHistogramDisplayFilter"
withInputParameters:nil];
return outHistogramImage;
}
Here is the image to be filtered:
Original Image
And here is my generated Histogram image:
Histogram from my function
Viewing the image in Mac Preview app or Photos app should show the correct histogram with the majority of the colors in the center of the histogram.
Any help is greatly appreciated.
Disabling Color Management fixed the issue:
NSDictionary *options = #{(id)kCIImageColorSpace : (id)kCFNull};
CIImage *inputImage = [CIImage imageWithCGImage: image options:options];

What is the best way to display a single-paged pdf as an image?

I would like to display in an NSView a single-paged PDF.
So far, I have two solutions but they both have downsides. Can anyone help me with any of these downsides?
First solution: with NSImage and NSImageView
NSString *path= [[NSBundle mainBundle] pathForResource:name ofType:#"pdf"];
NSImage * image = [[NSImage alloc] initWithContentsOfFile:path] ;
NSImageView * imageView = [[NSImageView alloc] init] ;
imageView.frame = NSMakeRect(0, 0, 2*image.size.width, 2*image.size.height) ;
imageView.image = image ;
imageView.imageScaling = NSImageScaleAxesIndependently ;
return imageView
Downsides:
the image is not anti-aliased
I don't understand why the factor 2 is needed. Why does my PDF is displayed smaller in an NSView than it is with the Finder?
Second solution: with PDFDocument and PDFView
NSString *path= [[NSBundle mainBundle] pathForResource:name ofType:#"pdf"];
NSURL *urlPDF = [NSURL fileURLWithPath:path] ;
PDFDocument * myPDFDocument = [[PDFDocument alloc] initWithURL:urlPDF] ;
PDFView *myPDFView = [[PDFView alloc] init] ;
myPDFView.document = myPDFDocument ;
PDFPage * firstPage = [myPDFDocument pageAtIndex:0] ;
NSRect myBounds = [firstPage boundsForBox:kPDFDisplayBoxMediaBox] ;
NSRect myNewBounds = NSMakeRect(0, 0, myBounds.size.width*2, myBounds.size.height*2+5) ;
myPDFView.frame = myNewBounds ;
myPDFView.autoScales = YES ;
return myPDFView ;
Downsides:
I am able to select the text of my pdf, I can zoom in or zoom out. But I would like my PDF document to be displayed as an image, without these possibilities
I don't understand why the factor 2 is needed. Why is my PDF displayed smaller in an NSView than it is with the Finder?
There are some margins around my image
I'm not seeing the problems you describe with NSImageView. I implemented a nib-based window and NSImageView. In my case I have an overlapping sibling view, so I turned CALayers turned on in the nib. I'm on 10.9.2. Sizing is normal (1x) and the text in my PDF is anti-aliased (sub-pixel I think, since I see colors when I blow it up). I do have scaling NONE - maybe scaling is preventing anti-aliased text?
Otherwise my guess is there's something different about your views or or PDF content. Try a simpler PDF and/or a nib-based view and if it works, you can look for differences.

Replace NSTextattachement Image on NSMutableattributedString

I'm building an UITextView with text and images (Subclassing NSTextstorage for displaying my content)
I'm having textcontent with images URLs.
So my problem is that i need download all the images if they're not cached.
So i want to first insert a placeholder image, download the image and then replace the placeholder image by the downloaded one.
Here's how i do my stuff.
First, i'm formatting my text with images url by replacing all urls with this tag :
[IMG]url[/IMG]
Then i'm using a regex to get all these tags.
I'm testing if there's a cached image or not. If not, i extract all the urls, download them and cache them.
I've created an NSObject class ImageCachingManager and declared a delegate method called when an image has been downloaded :
#protocol ImageCachingManagerDelegate <NSObject>
- (void)managerDidCacheImage:(UIImage *)image forUrl:(NSString *)url;
#end
Like this, I tough that I could use the url of the image got by the delegate method to search the matching url in my NSTextstorage attributedString and replace the current NSTextattachement image by the downloaded one.
But I don't know how to do that...
Thanks for help !
I'm working on something very similar to this at the moment and think this might help. The code is very much alpha but hopefully it will get you to the next step - I'll step through:
Overall Cycle
1. Find you image tags in the full text piece using Reg Ex or XPath - personally i find Hppl to be more powerful but if your content is well structured and reliable, regex is probably fine.
https://github.com/topfunky/hpple
Reduce the space of this match to 1 character and store that range - A textAttachment occupies only 1 character of space within a textview so it's best to reduce this to 1 otherwise when you replace your first match of characters in a range with the first textattachment the next range marker becomes out of date which will lead to issues. Depending on how much processing you need to do this text input during init, this is an important step, i have to do a lot of processing on the text and the ranges change during this parsing so I created an array of special characters that I know is never going to be in the inputs and push these single characters into the reserved space, at the same time i store this special character and the src of the image in an array of a very simple NSObject subclass that stores the SpecialChar, ImgSrc plus has space for the NSRange but i basically find the special character later in the process again because it has been moved about since this point and then set the nsrange at the very end of processing - this may not be necessary in your case but the principle is the same; You need a custom object with NsRange (which will become a text attachment) and the imgSource.
Loop through this array to add placeholder imageAttachments to your attributed string. You can do this by adding a transparent image or a 'loading' image. You could also check your cache for existing images during this point and skipping the placeholder if it exists in cache.
Using your delegate, when the image is successfully downloaded, you need to replace the current attachment with your new one. By replacing the placeholder in the range you've already stored in your object. Create a placeholder attributedString with the NSTextAttachment and then replace that range as below.
Some sample code:
Steps 1 & 2:
specialCharsArray = [[NSArray alloc]initWithObjects:#"Û", #"±", #"¥", #"å", #"æ", #"Æ", #"Ç", #"Ø", #"õ", nil];
//using Hppl
NSString *allImagesXpathQueryString = #"//img/#src";
NSArray *imageArray = [bodyTextParser searchWithXPathQuery:allImagesXpathQueryString];
//
imageRanges = [[NSMutableArray alloc] init];
if([imageArray count]){
for (TFHppleElement *element in imageArray) {
int i = 0;
NSString *imgSource = [[[element children] objectAtIndex:0] content];
NSString *replacementString = [specialCharsArray objectAtIndex:i];
UIImage *srcUIImage = [UIImage imageNamed:imgSource];
[srcUIImage setAccessibilityIdentifier:imgSource]; //only needed if you need to reference the image filename later as it's lost in a UIImage if stored directly
//imagePlacement is NSObject subclass to store the range, replacement and image as above
imagePlacement *foundImage = [[imagePlacement alloc]init] ;
[foundImage initWithSrc:srcUIImage replacement:replacementString];
[imageRanges addObject:foundImage];
i++;
}
Step 3:
-(void)insertImages{
if ([imageRanges count]) {
[self setScrollEnabled:NO]; //seems buggy with scrolling on
int i = 0; //used to track the array placement for tag
for(imagePlacement *myImagePlacement in imageRanges){
// creates a text attachment with an image
NSMutableAttributedString *placeholderAttString = [[NSMutableAttributedString alloc]initWithAttributedString:self.attributedText];
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
//scales image down to ration of width of view - you probably don't need this
CGSize scaleToView = imagePlacement.imgSrc.size;
scaleToView.width = self.frame.size.width;
scaleToView.height = (self.frame.size.width/imagePlacement.imgSrc.size.width)*imagePlacement.imgSrc.size.height;
attachment.image = [self imageWithColor:[UIColor clearColor] andSize:scaleToView];
NSMutableAttributedString *imageAttrString = [[NSAttributedString attributedStringWithAttachment:attachment] mutableCopy];
[self setAttributedText:placeholderAttString];
i++;
}
}
[self setScrollEnabled:YES];
}
- (UIImage *)imageWithColor:(UIColor *)color andSize:(CGSize) size {
CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}

NSImage and PDFImageRep caching still draws at only one resolution

I have an NSImage, initialized with PDF data, created like this:
NSData* data = [view dataWithPDFInsideRect:view.bounds];
slideImage = [[NSImage alloc] initWithData:data];
The slideImage is now the size of the view.
When I try to render the image in an NSImageView, it only draws sharp when the image view is exactly the original size of the image, even if you clear the cache or change the image size. I tried setting the cacheMode to NSImageCacheNever, which also didn't work. The only image rep in the image is the PDF one, and when I render it to a PDF file it shows that it's vector.
As a workaround, I create a NSBitmapImageRep with a different size, call drawInRect on the original image, and put the bitmap representation inside a new NSImage and render that, which works, but it feels like it's not optimal:
- (NSBitmapImageRep*)drawToBitmapOfWidth:(NSInteger)width
andHeight:(NSInteger)height
withScale:(CGFloat)scale
{
NSBitmapImageRep *bmpImageRep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL
pixelsWide:width * scale
pixelsHigh:height * scale
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSCalibratedRGBColorSpace
bitmapFormat:NSAlphaFirstBitmapFormat
bytesPerRow:0
bitsPerPixel:0
];
bmpImageRep = [bmpImageRep bitmapImageRepByRetaggingWithColorSpace:
[NSColorSpace sRGBColorSpace]];
[bmpImageRep setSize:NSMakeSize(width, height)];
NSGraphicsContext *bitmapContext = [NSGraphicsContext graphicsContextWithBitmapImageRep:bmpImageRep];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:bitmapContext];
[self drawInRect:NSMakeRect(0, 0, width, height) fromRect:NSZeroRect operation:NSCompositeCopy fraction:1];
[NSGraphicsContext restoreGraphicsState];
return bmpImageRep;
}
- (NSImage*)rasterizedImageForSize:(NSSize)size
{
NSImage* newImage = [[NSImage alloc] initWithSize:size];
NSBitmapImageRep* rep = [self drawToBitmapOfWidth:size.width andHeight:size.height withScale:1];
[newImage addRepresentation:rep];
return newImage;
}
How can I get the PDF to render nicely at any size without resorting to hacks like mine?
The point of NSImage is that you create it with the size (in points) that you want it to be. The backing representation can be vector based (e.g. PDF), and the NSImage is resolution independent (i.e. it supports different pixels per point), but the NSImage still has a fixed size (in points).
One one the points of an NSImage is that it will / can add a cache representation to speed up subsequent drawing.
If you need to draw a PDF to multiple sizes, and you want to use an NSImage, you're probably best of creating an NSImage for your given target size. If you want to, you can keep the NSPDFImageRef around -- I don't think it'll save you much.
We tried the following:
NSPDFImageRep* rep = self.representations.lastObject;
return [NSImage imageWithSize:size flipped:NO drawingHandler:^BOOL (NSRect dstRect)
{
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
[rep drawInRect:dstRect fromRect:NSZeroRect operation:NSCompositeCopy fraction:1 respectFlipped:YES hints:#{
NSImageHintInterpolation: #(NSImageInterpolationHigh)
}];
return YES;
}];
And that does give you nice results when scaling up, but makes for blurry images
when scaling down.

Rescale image in imageview

In my app I can take a photo from the camera and display it in an imageview, but what I want to be able to do is rescale/resize the resolution of the image so it's not as big and does not take up so much memory in the app.
Here is the code I use for displaying the image in the imageview:
image = [info objectForKey:UIImagePickerControllerOriginalImage];
[ImageView1 setImage:image]; // "ImageView1" name of any UImageView.
[self dismissViewControllerAnimated:YES completion:NULL];
I want the image scaled down as the image can also be sent via email, so it must be nice and small.
You can try this code:
+ (UIImage*)imageWithImage:(UIImage*)image
scaledToSize:(CGSize)newSize;
{
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
As far as storage of the image, the fastest image format to use with the iPhone is PNG, because it has optimizations for that format. However, if you want to store these images as JPEGs, you can take your UIImage and do the following:
NSData *dataForJPEGFile = UIImageJPEGRepresentation(theImage, 0.6);
This creates an NSData instance containing the raw bytes for a JPEG image at a 60% quality setting. The contents of that NSData instance can then be written to disk or cached in memory.
You can refer this link also: UIImage: Resize, then Crop
Hope this will helps you.

Resources