I am using Xcode 3.2.3 with iOS 4 SDK.
I am preparing a small app for plotting values on a graph. To this end I have used the ECGraph library. I downloaded the sample app and tuned it a bit to suit my purposes. I want the graph to plot time on the X-axis in hours and a simple int value on the Y-axis.
My problem: When I do select the option of creating a point in ECGraph as (date, value), I can see the graph if the scale on the X-axis i.e. time unit is date. If i change the time unit to HOUR, the graph is a single line on the Y-axis where the Y-axis plots are correct, but the X-axis points are always the origin.
I have added the code from my UIView file here. Its simply the one taken from the demo app, given with the ECGraph lib download and then tuned for my stuff.
DisplayView.m:
//
// DisplayView.m
// ECGraphic
//
// Created by ris on 10-4-17.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import "DisplayView.h"
#import "ECCommon.h"
#import "ECGraphPoint.h"
#import "ECGraphLine.h"
#import "ECGraphItem.h"
#implementation DisplayView
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Initialization code
}
return self;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
CGContextRef _context = UIGraphicsGetCurrentContext();
ECGraph *graph = [[ECGraph alloc] initWithFrame:CGRectMake(10, 50, 300, 350) withContext:_context isPortrait:YES];
ECGraphPoint *point7 = [[ECGraphPoint alloc] init];
point7.yValue = 7;
point7.xDateValue = [ECCommon dOfS:#"08" withFormat:kDEFAULT_HOUR_FORMAT];
ECGraphPoint *point8 = [[ECGraphPoint alloc] init];
point8.yValue = 13;
point8.xDateValue = [ECCommon dOfS:#"09" withFormat:kDEFAULT_HOUR_FORMAT];
ECGraphPoint *point9 = [[ECGraphPoint alloc] init];
point9.yValue = 1;
point9.xDateValue = [ECCommon dOfS:#"10" withFormat:kDEFAULT_HOUR_FORMAT];
ECGraphPoint *point10 = [[ECGraphPoint alloc] init];
point10.yValue = 3;
point10.xDateValue = [ECCommon dOfS:#"11" withFormat:kDEFAULT_HOUR_FORMAT];
//NSArray *pts3 = [[NSArray alloc] initWithObjects:point7,point8,point9, point10, nil];
NSArray *pts3 = [[NSArray alloc] initWithObjects:point7,point8, nil];
ECGraphLine *line3 = [[ECGraphLine alloc] init];
line3.isXDate = YES;
line3.points = pts3;
NSArray *lines = [[NSArray alloc] initWithObjects:line3,nil];
[graph setXaxisTitle:#"Hours"];
[graph setYaxisTitle:#"Energy consumed in Watts"];
[graph setGraphicTitle:#"Weekly consumption of your device"];
[graph setXaxisDateFormat:kDEFAULT_HOUR_FORMAT];
[graph setDelegate:self];
[graph setBackgroundColor:[UIColor colorWithRed:220/255.0 green:220/255.0 blue:220/255.0 alpha:1]];
[graph setPointType:ECGraphPointTypeCircle];
[graph drawCurveWithLines:lines lineWidth:2 color:[UIColor blackColor]];
}
- (void)dealloc {
[super dealloc];
}
#end
Related
using default viewcontroller and mainstoryboard:
using pod install to setup the library.
This is a seggested Filtering live video test code,but it does not work on my iPhone6s.
GPUImage
#import "ViewController.h"
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
enter code here
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
GPUImageFilterGroup *group=[[GPUImageAmatorkaFilter alloc] init];
GPUImageFilter *customFilter=(GPUImageFilter *)[group filterAtIndex:0];
NSLog(#"%lu",(unsigned long)[group filterCount]);
GPUImageView *filteredVideoView = [[GPUImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 375, 480)];
[self.view addSubview:filteredVideoView];
[videoCamera addTarget:customFilter];
[customFilter addTarget:filteredVideoView];
[videoCamera startCameraCapture];
}
#end
I'm trying to achieve the square video recording like 300*300 so I choose GPUImage but its not working on IOS 7 and giving errors like [UIView nextAvailableTextureIndex]: unrecognized selector sent to instance the error starts when we build the even the sample code
when trying to save the GPUImageVideoCamera
some times its stucks at [movieWriter startRecording];
is the GPUImage compatible with ios 7 or we have made some changes ?
here is the code
- (void)viewDidLoad
{
[super viewDidLoad];
videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
videoCamera.horizontallyMirrorFrontFacingCamera = NO;
videoCamera.horizontallyMirrorRearFacingCamera = NO;
filter = [[GPUImageSepiaFilter alloc] init];
initWithRotation:kGPUImageRotateRightFlipVertical];
[videoCamera addTarget:filter];
GPUImageView *filterView = (GPUImageView *)self.view;
[filter addTarget:filterView];
sharing
NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/Movie.m4v"];
unlink([pathToMovie UTF8String]); // If a file already exists, AVAssetWriter won't let you record new frames, so delete the old movie
NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie];
movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(480.0, 640.0)];
[filter addTarget:movieWriter];
}
- (IBAction)stopRecording:(id)sender {
[filter removeTarget:movieWriter];
videoCamera.audioEncodingTarget = nil;
[movieWriter finishRecording];
}
- (IBAction)startRecording:(id)sender {
videoCamera.audioEncodingTarget = movieWriter;
[movieWriter startRecording];
[videoCamera startCameraCapture];
}
My guess is that you modified the .xib or storyboard and didn't set the class of the view that is showing the camera preview to GPUImageView.
So I have 2 views, one of them is a UITableVew where a user can populate cells by adding them. The second view is the information when they add them (Name, date, company and a place to scan a barcode.). Well when they scan that image, they can see the image of what they scanned (Done with Zbar barcode scanner). So the main question is how can I exactly save different images in each different cell that the user adds?
Code:
Zbar:
- (IBAction)cameraButtonTapped:(id)sender
{
// Check for camera
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == YES) {
// Create image picker controller
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// Set source to the camera
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
// Delegate is self
imagePicker.delegate = self;
// Show image picker
[self presentModalViewController:imagePicker animated:YES];
}
}
- (void) imagePickerController: (UIImagePickerController*)reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// ADD: get the decode results
id<NSFastEnumeration> results =
[info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
// EXAMPLE: just grab the first barcode
break;
// EXAMPLE: do something useful with the barcode data
resultText.text = symbol.data;
// EXAMPLE: do something useful with the barcode image
resultImage.image =
[info objectForKey: UIImagePickerControllerOriginalImage];
// ADD: dismiss the controller (NB dismiss from the *reader*!)
[reader dismissModalViewControllerAnimated:YES];
}
-(UIView*)CommomOverlay{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,480)];
UIImageView *TopBar = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,58)];
[TopBar setImage:[UIImage imageNamed:#""]];
[view addSubview:TopBar];
UILabel *Toplabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 9, 300, 30)];
[Toplabel setFont:[UIFont fontWithName:#"Heiti TC light" size:22]];
[Toplabel setTextAlignment:UITextAlignmentCenter];
[Toplabel setBackgroundColor:[UIColor clearColor]];
[Toplabel setTextColor:[UIColor lightGrayColor]];
[Toplabel setNumberOfLines:1];
[Toplabel setText:#"Turn your device sideways to scan"];
[TopBar addSubview:Toplabel];
UIImageView *FrameImg = [[UIImageView alloc] initWithFrame:CGRectMake(40,50,240,370)];
[FrameImg setImage:[UIImage imageNamed:#"scanImage.png"]];
[view addSubview:FrameImg];
return view;
}
- (IBAction) scanButtonTapped
{
// ADD: present a barcode reader that scans from the camera feed
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
reader.supportedOrientationsMask = ZBarOrientationMaskAll;
ZBarImageScanner *scanner = reader.scanner;
// TODO: (optional) additional reader configuration here
// EXAMPLE: disable rarely used I2/5 to improve performance
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
// present and release the controller
reader.cameraOverlayView = [self CommomOverlay];
[self presentModalViewController: reader
animated: YES];
}
I did think using core data but i cant find a tutorial anywhere. Then I thought saving it in the apps Documents folder and i think that would be the bes way for me. I am new to this so descriptive code would help :)
Update:
- (IBAction)save:(id)sender {
NSManagedObjectContext *context = [self managedObjectContext];
UIImage *image = resultImage.image;
NSData *imageData = UIImagePNGRepresentation(image); //convert image into .png format.
NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it
NSString *documentsDirectory = [paths objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"/%#KYRO Receipts Images/Barcode.png", resultImage]]; //add our image to the path
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; //finally save the path (image)
NSLog(#"image saved");
if (self.device) {
// Update existing device
[self.device setValue:self.nameOfItem.text forKey:#"name"];
[self.device setValue:self.dateOfPurchase.text forKey:#"date"];
[self.device setValue:self.companyOfItem.text forKey:#"company"];
} else {
//
NSManagedObject *newDevice = [NSEntityDescription insertNewObjectForEntityForName:#"Receipt" inManagedObjectContext:context];
[newDevice setValue:self.nameOfItem.text forKey:#"name"];
[newDevice setValue:self.dateOfPurchase.text forKey:#"date"];
[newDevice setValue:self.companyOfItem.text forKey:#"company"];
}
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error]) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
[WTStatusBar setStatusText:#"Saving data..." animated:YES];
[self performSelector:#selector(setTextStatusProgress3) withObject:nil afterDelay:0.1];
[self.navigationController popViewControllerAnimated:YES];
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
If you're already using Core Data, then depending on the size of the images you could either convert them to NSData and save them directly within Core Data (if they're small) or you can save them within the documents directory and save the file name within Core Data.
Since a full Core Data tutorial is beyond the scope here, I'll just go over saving the image to the documents directory under a unique name. Note that some of the code below was adapted from "iOS Programming: The Big Nerd Ranch Guide".
// Method to save your image file. Returns the file name for you to save in Core Data or elsewhere.
- (NSString *)saveImage:(UIImage *)image {
// Generate a unique key to name the image file
CFUUIDRef newUniqueID = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef newUniqueIDString = CFUUIDCreateString(kCFAllocatorDefault, newUniqueID);
NSString *imgkey = (__bridge NSString *)newUniqueIDString;
// Get a path for the image file in the documents directory
NSString *imagePath = [self imagePathForKey:imgkey];
// Convert the UIImage into NSData and save it to the documents directory
NSData *imageData = UIImageJPEGRepresentation(img, 0.5);
[imageData writeToFile:imagePath atomically:YES];
// Clean up
CFRelease(newUniqueIDString);
CFRelease(newUniqueID);
return imgkey;
}
// Method to provide the image path for saving/retrieving the image
- (NSString *)imagePathForKey:(NSString *)key {
NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [documentDirectories objectAtIndex:0];
return [documentDirectory stringByAppendingPathComponent:key];
}
The following method retrieves the image:
- (UIImage *)imageForKey:(NSString *)imgkey {
result = [UIImage imageWithContentsOfFile:[self imagePathForKey:imgkey thumbnail:FALSE]];
if (!result) {
// File not found - add code here as needed (to return default image or whatever)
}
return result;
}
Note that if you are planning to display multiple images in the table at the same time, you must be careful to ensure they are small, otherwise you may run into memory issues. In this case you would want to convert them into a thumbnail form for the table view, then display the full size image only in the detail view (how to generate a thumbnail would be a separate question).
I need to display a detailed view controller with multiple labels when a row in a table view is clicked. The labels I am displaying are of dynamic height based on the content, which is being read from the iPhone's internal calendar. I have been able to implement the loading of detail views based on which row in the table view has been selected. My issue is that the previous detail view does not get cleared up when a new row is clicked. Especially in the case when my previous detail view had longer labels and the new detail view has shorter labels, I can see the content of the previous labels below the new one. How can I clear up the entire Detail View controller before reloading it with the new row's data. Following is the code I am using:
RootViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (mdController == nil) {
MtgDetailController *aController = [[MtgDetailController alloc] initWithNibName:#"MtgDetailController" bundle:nil];
self.mdController = aController;
[aController release];
}
self.mdController.mtgIndex = indexPath.row;
// mdController.mtgIndex = indexPath.row;
// [mdController setMtgIndex:indexPath.row];
// NSInteger temp = indexPath.row;
UIActionSheet *action = [[UIActionSheet alloc]
initWithTitle:#"Select an Option"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"Open Meeting", #"Dial into meeting", nil];
[action showInView:self.parentViewController.view];
[action release];
}
MtgDetailController.m (This is the Detail View Controller)
-(void) viewDidAppear:(BOOL)animated {
// [self reloadInputViews];
Smart_MeetingAppDelegate *myDelegate = (Smart_MeetingAppDelegate *)[[UIApplication sharedApplication]delegate];
CGRect scrollViewFrame = CGRectMake(0, 0, 320, 460);
NSString *title = [myDelegate.titles objectAtIndex:self.mtgIndex];
NSString *mtg_time = [myDelegate.mtg_times objectAtIndex:self.mtgIndex];
NSString *loc = #"Conf Room 123";
// detail = #"test mtg test mtg. Dial number: 3334445555, (333)444-5555, 333-333-5555. ID: 4455333344, Password: 6576567";
detail = [myDelegate.detail_array objectAtIndex:self.mtgIndex];
NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:#"\\b[0-9]+(\\-)?(\\))?(\\.)?(\\s)?([0-9]+)?(\\-)?(\\.)?(\\s)?([0-9]+)?(\\-)?(\\.)?(\\s)?([0-9]+)?\\b" options:NSRegularExpressionCaseInsensitive error:nil];
NSArray* matches = [regex matchesInString:detail options:0 range:NSMakeRange(0, [detail length])];
[regex release];
unichar chr[1] = {'\n'};
NSString *singleCR = [NSString stringWithCharacters:(const unichar *)chr length:1];
NSString *titleRow = [NSString stringWithFormat:#"%# %# %#", title, singleCR, mtg_time];
NSMutableAttributedString *attrTitle = [NSMutableAttributedString attributedStringWithString:titleRow];
[attrTitle setFont:[UIFont systemFontOfSize:18] range:[titleRow rangeOfString:title]];
[attrTitle setFont:[UIFont systemFontOfSize:16] range:[titleRow rangeOfString:mtg_time]];
NSMutableAttributedString *attrLoc = [NSMutableAttributedString attributedStringWithString:loc];
NSMutableAttributedString *attrDetail = [NSMutableAttributedString attributedStringWithString:detail];
[attrDetail setFont:[UIFont systemFontOfSize:16]];
CGSize suggestedSize = [attrTitle sizeConstrainedToSize:CGSizeMake(300, FLT_MAX)];
CGRect frame1 = CGRectMake(10, 15, 300, suggestedSize.height);
OHAttributedLabel *lblTitle = [[OHAttributedLabel alloc] initWithFrame:frame1];
lblTitle.numberOfLines = 0;
CGSize size2 = [attrLoc sizeConstrainedToSize:CGSizeMake(300, FLT_MAX)];
CGRect frame2 = CGRectMake(10, suggestedSize.height+15+5, 300, size2.height);
OHAttributedLabel *lblLocation = [[OHAttributedLabel alloc] initWithFrame:frame2];
CGFloat temp = size2.height+suggestedSize.height;
CGSize size3 = [attrDetail sizeConstrainedToSize:CGSizeMake(300, FLT_MAX)];
CGRect frame3 = CGRectMake(10, temp+15+5, 300, size3.height);
OHAttributedLabel *lblDescription = [[OHAttributedLabel alloc] initWithFrame:frame3];
lblDescription.numberOfLines = 0;
lblTitle.attributedText = attrTitle;
lblLocation.attributedText = attrLoc;
lblDescription.attributedText = attrDetail;
for (NSTextCheckingResult *m in matches) {
NSString *num = [detail substringWithRange:m.range];
NSRange linkRange = [detail rangeOfString:num];
[lblDescription addCustomLink:[NSURL URLWithString:#"user://certa"] inRange:linkRange];
}
lblDescription.delegate = self;
[self.view addSubview:lblTitle];
[self.view addSubview:lblDescription];
[self.view addSubview:lblLocation];
[lblTitle release];
[lblLocation release];
[lblDescription release];
}
You add three new instances of OHAttributedLabel to your detail view every time viewDidAppear: executes. You never remove these views. You need to save references to them (lblTitle, lblDescription, and lblLocation) in your MtgDetailController, and either remove them or reuse them the next time viewDidAppear: executes.
Add three properties to your MtgDetailController:
#property (retain) UILabel *lblTitle;
#property (retain) UILabel *lblDescription;
#property (retain) UILabel *lblLocation;
(Don't forget to #synthesize them too.)
At the top of viewDidAppear:, remove the labels from their superviews:
- (void)viewDidAppear:(BOOL)animated {
[self.lblTitle removeFromSuperview];
[self.lblDescription removeFromSuperview];
[self.lblLocation removeFromSuperview];
...
At the bottom of viewDidAppear:, save your newly-created labels in the properties:
self.lblTitle = lblTitle;
self.lblLocation = lblLocation;
self.lblDescription = lblDescription;
I've been struggling with adding assets from the iPhone Photo Library to a AVMutableComposition and then export them. Here is what I got:
Finding the assets: (here I grab the AVURLAsset)
-(void) findAssets {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Enumerate just the photos and videos group by using ALAssetsGroupSavedPhotos.
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
// Within the group enumeration block, filter to enumerate just videos.
[group setAssetsFilter:[ALAssetsFilter allVideos]];
[group enumerateAssetsUsingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop){
// The end of the enumeration is signaled by asset == nil.
if (alAsset) {
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
NSURL *url = [representation url];
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
// Do something interesting with the AV asset.
[thumbs addObject:alAsset];
[assets addObject:avAsset];
}else if(alAsset == nil){
[self createScroll];
}
}];
}
failureBlock: ^(NSError *error) {
// Typically you should handle an error more gracefully than this.
NSLog(#"No groups");
}];
[library release];
}
Here I add a asset to my composition (I use the first object in the array for testing only.
-(void) addToCompositionWithAsset:(AVURLAsset*)_asset{
NSError *editError = nil;
composition = [AVMutableComposition composition];
AVURLAsset* sourceAsset = [assets objectAtIndex:0];
Float64 inSeconds = 1.0;
Float64 outSeconds = 2.0;
// calculate time
CMTime inTime = CMTimeMakeWithSeconds(inSeconds, 600);
CMTime outTime = CMTimeMakeWithSeconds(outSeconds, 600);
CMTime duration = CMTimeSubtract(outTime, inTime);
CMTimeRange editRange = CMTimeRangeMake(inTime, duration);
[composition insertTimeRange:editRange ofAsset:sourceAsset atTime:composition.duration error:&editError];
if (!editError) {
CMTimeGetSeconds (composition.duration);
}
}
And finally I export the comp and here it crashes
-(void)exportComposition {
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetPassthrough];
NSLog (#"can export: %#", exportSession.supportedFileTypes);
NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [dirs objectAtIndex:0];
NSString *exportPath = [documentsDirectoryPath stringByAppendingPathComponent:EXPORT_NAME];
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
NSURL *exportURL = [NSURL fileURLWithPath:exportPath];
exportSession.outputURL = exportURL;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;//#"com.apple.quicktime-movie";
[exportSession exportAsynchronouslyWithCompletionHandler:^{
NSLog (#"i is in your block, exportin. status is %d",
exportSession.status);
switch (exportSession.status) {
case AVAssetExportSessionStatusFailed:
case AVAssetExportSessionStatusCompleted: {
[self performSelectorOnMainThread:#selector (exportDone:)
withObject:nil
waitUntilDone:NO];
break;
}
};
}];
}
Does anyone have an idea of what it might be? It crashes on
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetPassthrough];
And I tried different presets and outputFileTypes.
Thanks
* SOLVED *
I have to answer my own question now when I have solved. It's amazing that I've been struggling with this for a whole day and then I fix it right after posting a question :)
I changed and moved:
composition = [AVMutableComposition
composition];
to:
composition = [[AVMutableComposition
alloc] init];
I think I was too tired when I was working on this yesterday. Thanks guys!