Вы можете попробовать этот код. Я нашел его раньше, когда у меня возникла проблема, похожая на вашу.
if (isset($_GET['q1mrks']) && isset($_GET['marks']) && isset($_GET['qt1'])) {
$Q1mrks = $_GET['q1mrks'];
$marks = $_GET['marks'];
$qt1 = $_GET['qt1'];
$qtype_qry = mysql_query("
SELECT *
FROM s_questiontypes
WHERE quetype_id = '$qt1'
");
$row = mysql_fetch_assoc($qtype_qry);
$qcode = $row['quetype_code'];
$sq_qry = "
SELECT *
FROM s_question
WHERE quetype_code = '$qcode'
ORDER BY RAND() LIMIT $Q1mrks
";
$sq_qry = mysql_query("
SELECT *
FROM s_question
WHERE quetype_code = '$qcode'
LIMIT $Q1mrks
");
while ($qrow = mysql_fetch_array($sq_qry)) {
$qm = $qrow['marks'] . "<br />";
$total += $qm . "<br />";
}
echo $total . "/" . $marks;
}
Перейти к обработке изображения, чтобы узнать, как преобразовать UIImage
в NSData
(что использует Core Data)
Или загрузить с github
Настройка основных данных:
Настройте два объекта: полное разрешение и миниатюру. Полные разрешения - сохранить исходное изображение. Миниатюра для хранения меньшей версии, которая будет использоваться внутри приложения. Например, вы можете использовать меньшую версию в обзоре UICollectionView
.
Изображения сохраняются как Binary Data
в Core Data
. Соответствующим типом в Foundation
является NSData
. Вернитесь к UIImage
с помощью UIImage(data: newImageData)
Установите флажок «Разрешить внешнее хранилище» для полей «Двоичные данные». Это автоматически сохранит изображения в файловой системе, которые ссылаются на них в Core Data
Подключите два объекта, создав отношения «один к одному» между два.
Перейти к редактору en выберите Create NSManagedObjectSubclass. Это будет генерировать файлы с классами, представляющими подклассы управляемых объектов. Они будут отображаться в вашей структуре файла проекта.
Базовая установка ViewController:
Импортируйте следующее:
import UIKit
import CoreData
UIButtons
и UIImageView
в построителе интерфейса class ViewController: UIViewController {
// imageview to display loaded image
@IBOutlet weak var imageView: UIImageView!
// image picker for capture / load
let imagePicker = UIImagePickerController()
// dispatch queues
let convertQueue = dispatch_queue_create("convertQueue", DISPATCH_QUEUE_CONCURRENT)
let saveQueue = dispatch_queue_create("saveQueue", DISPATCH_QUEUE_CONCURRENT)
// moc
var managedContext : NSManagedObjectContext?
override func viewDidLoad() {
super.viewDidLoad()
imagePickerSetup() // image picker delegate and settings
coreDataSetup() // set value of moc on the right thread
}
// this function displays the imagePicker
@IBAction func capture(sender: AnyObject) { // button action
presentViewController(imagePicker, animated: true, completion: nil)
}
@IBAction func load(sender: AnyObject) { // button action
loadImages { (images) -> Void in
if let thumbnailData = images?.last?.thumbnail?.imageData {
let image = UIImage(data: thumbnailData)
self.imageView.image = image
}
}
}
}
Эта функция устанавливает значение managedContext
в правильной нити. Поскольку CoreData нуждается в выполнении всех операций в одном NSManagedObjectContext
в одном и том же потоке.
extension ViewController {
func coreDataSetup() {
dispatch_sync(saveQueue) {
self.managedContext = AppDelegate().managedObjectContext
}
}
}
Расширьте UIViewController
, чтобы он соответствовал UIImagePickerControllerDelegate
и UINavigationControllerDelegate
. Они необходимы для UIImagePickerController
.
Создайте функцию настройки, а также создайте функцию делегата imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?)
extension ViewController : UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerSetup() {
imagePicker.delegate = self
imagePicker.sourceType = UIImagePickerControllerSourceType.Camera
}
// When an image is "picked" it will return through this function
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
self.dismissViewControllerAnimated(true, completion: nil)
prepareImageForSaving(image)
}
}
Немедленно отпустите UIImagePickerController
, иначе приложение будет заморожено.
Обработка изображения:
Вызовите эту функцию внутри imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?)
.
timeIntervalSince1970
. Это возвращает NSTimerInterval
в секундах. Это хорошо преобразуется в Double
. Он будет служить уникальным идентификатором для изображений и как способ их сортировки. dispatch_async(convertQueue)
, чтобы сделать тяжелый подъем на отдельном потоке. UIImage
в NSData
, это делается с помощью UIImageJPEGRepresentation(image, 1)
. 1
представляет качество, где 1
является самым высоким, а 0
является самым низким. Он возвращает необязательный, поэтому я использовал необязательную привязку. NSData
. Код:
extension ViewController {
func prepareImageForSaving(image:UIImage) {
// use date as unique id
let date : Double = NSDate().timeIntervalSince1970
// dispatch with gcd.
dispatch_async(convertQueue) {
// create NSData from UIImage
guard let imageData = UIImageJPEGRepresentation(image, 1) else {
// handle failed conversion
print("jpg error")
return
}
// scale image, I chose the size of the VC because it is easy
let thumbnail = image.scale(toSize: self.view.frame.size)
guard let thumbnailData = UIImageJPEGRepresentation(thumbnail, 0.7) else {
// handle failed conversion
print("jpg error")
return
}
// send to save function
self.saveImage(imageData, thumbnailData: thumbnailData, date: date)
}
}
}
Эта функция выполняет фактическое сохранение.
dispatch_barrier_sync(saveQueue)
do try catch
для попытки сохранения Используя dispatch_barrier_sync(saveQueue)
, мы уверены, что можем безопасно хранить новое изображение и что новые сэки или нагрузки будут ждать, пока это не закончится.
Код:
extension ViewController {
func saveImage(imageData:NSData, thumbnailData:NSData, date: Double) {
dispatch_barrier_sync(saveQueue) {
// create new objects in moc
guard let moc = self.managedContext else {
return
}
guard let fullRes = NSEntityDescription.insertNewObjectForEntityForName("FullRes", inManagedObjectContext: moc) as? FullRes, let thumbnail = NSEntityDescription.insertNewObjectForEntityForName("Thumbnail", inManagedObjectContext: moc) as? Thumbnail else {
// handle failed new object in moc
print("moc error")
return
}
//set image data of fullres
fullRes.imageData = imageData
//set image data of thumbnail
thumbnail.imageData = thumbnailData
thumbnail.id = date as NSNumber
thumbnail.fullRes = fullRes
// save the new objects
do {
try moc.save()
} catch {
fatalError("Failure to save context: \(error)")
}
// clear the moc
moc.refreshAllObjects()
}
}
}
Для загрузки изображения:
extension ViewController {
func loadImages(fetched:(images:[FullRes]?) -> Void) {
dispatch_async(saveQueue) {
guard let moc = self.managedContext else {
return
}
let fetchRequest = NSFetchRequest(entityName: "FullRes")
do {
let results = try moc.executeFetchRequest(fetchRequest)
let imageData = results as? [FullRes]
dispatch_async(dispatch_get_main_queue()) {
fetched(images: imageData)
}
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
return
}
}
}
}
Функции, используемые для масштабирования изображения:
extension CGSize {
func resizeFill(toSize: CGSize) -> CGSize {
let scale : CGFloat = (self.height / self.width) < (toSize.height / toSize.width) ? (self.height / toSize.height) : (self.width / toSize.width)
return CGSize(width: (self.width / scale), height: (self.height / scale))
}
}
extension UIImage {
func scale(toSize newSize:CGSize) -> UIImage {
// make sure the new size has the correct aspect ratio
let aspectFill = self.size.resizeFill(newSize)
UIGraphicsBeginImageContextWithOptions(aspectFill, false, 0.0);
self.drawInRect(CGRectMake(0, 0, aspectFill.width, aspectFill.height))
let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
Основные данные не предназначены для сохранения больших двоичных файлов, таких как изображения. Вместо этого используйте Document Directory в файловой системе.
Вот пример кода для этого.
let documentsDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask, true).first as! String
// self.fileName is whatever the filename that you need to append to base directory here.
let path = documentsDirectory.stringByAppendingPathComponent(self.fileName)
let success = data.writeToFile(path, atomically: true)
if !success { // handle error }