From fc0d7f3113ae41673a3931220ce6f465df29a33f Mon Sep 17 00:00:00 2001 From: Brennan Gensch Date: Thu, 13 Apr 2017 09:23:09 -0500 Subject: [PATCH 1/4] Added imagePath property for preset-image in Sketch view. --- RNSketch/RNSketch.h | 1 + RNSketch/RNSketch.m | 8 ++++++++ RNSketch/RNSketchManager.m | 7 +++++++ index.ios.js | 5 ++++- 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/RNSketch/RNSketch.h b/RNSketch/RNSketch.h index af5bb99..3ddc214 100644 --- a/RNSketch/RNSketch.h +++ b/RNSketch/RNSketch.h @@ -29,5 +29,6 @@ @property (nonatomic, strong) NSString *imageType; @property (nonatomic, strong) UIColor *strokeColor; @property (nonatomic, assign) NSInteger strokeThickness; +@property (nonatomic, strong) NSURL *imageURL; @end diff --git a/RNSketch/RNSketch.m b/RNSketch/RNSketch.m index 484db32..59a9d0c 100644 --- a/RNSketch/RNSketch.m +++ b/RNSketch/RNSketch.m @@ -183,6 +183,14 @@ - (void)setStrokeColor:(UIColor *)strokeColor _strokeColor = strokeColor; } +- (void)setImageURL:(NSURL *)imageURL +{ + NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; + _image = [UIImage imageWithData:imageData]; + [self drawBitmap]; + [self setNeedsDisplay]; +} + - (void)setStrokeThickness:(NSInteger)strokeThickness { _path.lineWidth = strokeThickness; diff --git a/RNSketch/RNSketchManager.m b/RNSketch/RNSketchManager.m index 93ee9e4..9987ac7 100644 --- a/RNSketch/RNSketchManager.m +++ b/RNSketch/RNSketchManager.m @@ -36,6 +36,7 @@ @implementation RNSketchManager RCT_EXPORT_VIEW_PROPERTY(imageType, NSString); RCT_EXPORT_VIEW_PROPERTY(strokeColor, UIColor); RCT_EXPORT_VIEW_PROPERTY(strokeThickness, NSInteger); +RCT_EXPORT_VIEW_PROPERTY(imageURL, NSURL); #pragma mark - Lifecycle @@ -54,6 +55,7 @@ - (UIView *)view self.sketchView = [[RNSketch alloc] initWithFrame:CGRectZero]; } +<<<<<<< HEAD return self.sketchView; } @@ -61,6 +63,11 @@ - (UIView *)view RCT_EXPORT_METHOD(saveDrawing:(NSString *)encodedImage ofType:(NSString *)imageType +======= +#pragma mark - Exported methods + +RCT_EXPORT_METHOD(saveImage:(NSString *)encodedImage +>>>>>>> 4b1b0e6... Added image property that can be used by React Native to force an update to the native view resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { diff --git a/index.ios.js b/index.ios.js index e0e2f1c..d9578c4 100644 --- a/index.ios.js +++ b/index.ios.js @@ -12,6 +12,7 @@ export default class Sketch extends React.Component { onClear: PropTypes.func, strokeColor: PropTypes.string, strokeThickness: PropTypes.number, + imagePath: PropTypes.string, style: View.propTypes.style, }; @@ -22,7 +23,8 @@ export default class Sketch extends React.Component { onClear: () => {}, strokeColor: '#000000', strokeThickness: 1, - style: null, + image: null, + style: null }; constructor(props) { @@ -67,6 +69,7 @@ export default class Sketch extends React.Component { strokeColor={strokeColor} strokeThickness={strokeThickness} style={[this.style, this.props.style]} + imageURL={this.props.imagePath} /> ); } From e07a4f71378f1f297f28c13e9cdfbca3c012e19c Mon Sep 17 00:00:00 2001 From: Hank Brekke Date: Wed, 4 Oct 2017 16:48:11 -0500 Subject: [PATCH 2/4] Sync ImageData prop with state/props --- RNSketch/RNSketch.h | 2 +- RNSketch/RNSketch.m | 6 +++--- RNSketch/RNSketchManager.m | 8 +------- index.ios.js | 16 +++++++++++----- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/RNSketch/RNSketch.h b/RNSketch/RNSketch.h index 3ddc214..4a48229 100644 --- a/RNSketch/RNSketch.h +++ b/RNSketch/RNSketch.h @@ -29,6 +29,6 @@ @property (nonatomic, strong) NSString *imageType; @property (nonatomic, strong) UIColor *strokeColor; @property (nonatomic, assign) NSInteger strokeThickness; -@property (nonatomic, strong) NSURL *imageURL; +@property (nonatomic, strong) NSURL *imageData; @end diff --git a/RNSketch/RNSketch.m b/RNSketch/RNSketch.m index 59a9d0c..b40b0d5 100644 --- a/RNSketch/RNSketch.m +++ b/RNSketch/RNSketch.m @@ -116,7 +116,7 @@ - (void)drawCurve - (void)drawBitmap { - UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0); + UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, UIViewContentModeScaleAspectFit); // Paint background if fillColor property provided if (!_image && _fillColor) { @@ -183,9 +183,9 @@ - (void)setStrokeColor:(UIColor *)strokeColor _strokeColor = strokeColor; } -- (void)setImageURL:(NSURL *)imageURL +- (void)setImageData:(NSURL *)imageURLData { - NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; + NSData *imageData = [NSData dataWithContentsOfURL:imageURLData]; _image = [UIImage imageWithData:imageData]; [self drawBitmap]; [self setNeedsDisplay]; diff --git a/RNSketch/RNSketchManager.m b/RNSketch/RNSketchManager.m index 9987ac7..1f8b2fe 100644 --- a/RNSketch/RNSketchManager.m +++ b/RNSketch/RNSketchManager.m @@ -36,7 +36,7 @@ @implementation RNSketchManager RCT_EXPORT_VIEW_PROPERTY(imageType, NSString); RCT_EXPORT_VIEW_PROPERTY(strokeColor, UIColor); RCT_EXPORT_VIEW_PROPERTY(strokeThickness, NSInteger); -RCT_EXPORT_VIEW_PROPERTY(imageURL, NSURL); +RCT_EXPORT_VIEW_PROPERTY(imageData, NSURL); #pragma mark - Lifecycle @@ -55,7 +55,6 @@ - (UIView *)view self.sketchView = [[RNSketch alloc] initWithFrame:CGRectZero]; } -<<<<<<< HEAD return self.sketchView; } @@ -63,11 +62,6 @@ - (UIView *)view RCT_EXPORT_METHOD(saveDrawing:(NSString *)encodedImage ofType:(NSString *)imageType -======= -#pragma mark - Exported methods - -RCT_EXPORT_METHOD(saveImage:(NSString *)encodedImage ->>>>>>> 4b1b0e6... Added image property that can be used by React Native to force an update to the native view resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { diff --git a/index.ios.js b/index.ios.js index d9578c4..a7704ad 100644 --- a/index.ios.js +++ b/index.ios.js @@ -12,7 +12,7 @@ export default class Sketch extends React.Component { onClear: PropTypes.func, strokeColor: PropTypes.string, strokeThickness: PropTypes.number, - imagePath: PropTypes.string, + imageData: PropTypes.string, style: View.propTypes.style, }; @@ -35,11 +35,17 @@ export default class Sketch extends React.Component { flex: 1, backgroundColor: 'transparent', }; + + this.state = { + imageData: props.imageData + } } - state = { - imageData: null, - }; + componentWillReceiveProps(nextProps) { + this.setState({ + imageData: nextProps.imageData + }) + } onChange = (event) => { const { imageData } = event.nativeEvent; @@ -69,7 +75,7 @@ export default class Sketch extends React.Component { strokeColor={strokeColor} strokeThickness={strokeThickness} style={[this.style, this.props.style]} - imageURL={this.props.imagePath} + imageData={this.state.imageData} /> ); } From d3452ceba3ed7d723e5e0088ebdb0e87cec84df7 Mon Sep 17 00:00:00 2001 From: Hank Brekke Date: Fri, 6 Oct 2017 13:31:16 -0500 Subject: [PATCH 3/4] Clears ImageData when Reused Fixes https://github.com/jgrancher/react-native-sketch/pull/33/files#r143246512 --- index.ios.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.ios.js b/index.ios.js index a7704ad..a4e7e6a 100644 --- a/index.ios.js +++ b/index.ios.js @@ -23,7 +23,7 @@ export default class Sketch extends React.Component { onClear: () => {}, strokeColor: '#000000', strokeThickness: 1, - image: null, + imageData: null, style: null }; From 7777a509df3075db545070dc26ec3568b5b0aabe Mon Sep 17 00:00:00 2001 From: Hank Brekke Date: Fri, 13 Jul 2018 16:06:51 -0500 Subject: [PATCH 4/4] Added helper and docs for ImageData prop --- README.md | 7 +++++++ index.ios.js | 20 ++++++++++++++++++++ package.json | 3 ++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 79dcf06..cda03d1 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ Here are the `props` of the the component: | ---- | ---- | ------------- | ---- | | `fillColor` | `String` | `null` | The color of the sketch background. Default to null to keep it transparent! *Note: This is different from the `style.backgroundColor` property, as the former will be seen in your exported drawing image, whereas the latter is only used to style the view.* | | `imageType` | `String` | `png` | The type of image to export. Can be `png` or `jpg`. Default to `png` to get transparency out of the box. | +| `imageData` | `String` | `null` | PNG/JPEG image intepretation encoded with base64 to render on the drawing canvas. | | `onChange` | `Function` | `() => {}` | Callback function triggered after every change on the drawing. The function takes one argument: the actual base64 representation of your drawing.| | `onClear` | `Function` | `() => {}` | Callback function triggered after a `clear` has been triggered. | | `strokeColor` | `String` | `'#000000'` | The stroke color you want to draw with. | @@ -80,6 +81,12 @@ The component also has some instance methods: | `clear()` | `Promise` | Clear the drawing. This method is a Promise mostly to be consistent with `save()`, but you could simply type: `this.sketch.clear();` | | `save()` | `Promise` | Save the drawing to an image, using the defined props as settings (`imageType`, `fillColor`, etc...). The Promise resolves with an object containing the `path` property of that image. Ex: `this.sketch.save().then(image => console.log(image.path));` | +Here are a few static helper functions for the component: + +| Name | Return type | Comment | +| ---- | ----------- | ------- | +| `getImageDataFromFilePath` | `Promise` | Reads a JPEG or PNG file into base64 image data that can be rendered using the `imageData` prop. | + ## Examples The project contains a folder `examples` that contains few demos of how to use `react-native-sketch`. Just copy and paste the code to your React Native application. diff --git a/index.ios.js b/index.ios.js index 8c2d271..1e5c909 100644 --- a/index.ios.js +++ b/index.ios.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { NativeModules, requireNativeComponent, View, ViewPropTypes } from 'react-native'; +import RNFS from 'react-native-fs'; const SketchManager = NativeModules.RNSketchManager || {}; @@ -30,6 +31,25 @@ export default class Sketch extends React.Component { style: null }; + static getImageDataFromFilePath(filePath) { + const formats = { + "jpg": "image/jpg", + "jpeg": "image/jpg", + "png": "image/png" + } + const fileExtension = filePath.split('.').pop(); + const format = formats[fileExtension]; + + if (!format) { + throw new Error(`Unable to parse file extension .${fileExtension}`) + } + + return RNFS.readFile(filePath.path, 'base64') + .then((base64) => { + return `data:${format};base64,${base64}`; + }) + } + constructor(props) { super(props); diff --git a/package.json b/package.json index 3c37032..3eda04b 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "A react-native component for touch-based drawing", "main": "index.ios.js", "dependencies": { - "prop-types": "^15.5.10" + "prop-types": "^15.5.10", + "react-native-fs": "^2.10.14" }, "devDependencies": { "babel-eslint": "^7.2.3",