diff --git a/README.0.9.2.MD b/README.0.9.2.MD index 24c188f7..3f399694 100644 --- a/README.0.9.2.MD +++ b/README.0.9.2.MD @@ -5,12 +5,12 @@ Add text or icon watermark to your images ## sample

- - - - - - + + + + + +

## Installation diff --git a/README.MD b/README.MD index a3ced587..a28a8bb9 100644 --- a/README.MD +++ b/README.MD @@ -1,6 +1,6 @@
- react native image marker Logo + react native image marker Logo

react native image marker

Add text or icon watermarks to images
@@ -29,13 +29,15 @@ * text align * padding * relative position + * background border radius * Compatible with both Android and iOS ## Sample - - - +

+ + +

## Usage @@ -53,7 +55,7 @@ ##### Sample - + ##### Example @@ -110,7 +112,7 @@ Marker.markText(options); ##### Sample - + ##### Example @@ -165,7 +167,7 @@ Marker.markText(options); ##### Sample - + ##### Example @@ -211,6 +213,71 @@ ImageMarker.markText(options); ``` +#### Text background border radius + +##### API + + +[TextBackgroundType.cornerRadius](https://jimmydaddy.github.io/react-native-image-marker/enums/TextBackgroundType.html#cornerRadius) + +##### Sample + + + + +##### Example + + +```typescript +import Marker, { Position } from "react-native-image-marker" +··· +const options = { + // background image + backgroundImage: { + src: require('./images/test.jpg'), + scale: 1, + }, + watermarkTexts: [{ + text: 'text marker normal', + positionOptions: { + position: Position.center, + }, + style: { + color: '#FC0700', + fontSize: 30, + fontName: 'Arial', + shadowStyle: { + dx: 10, + dy: 10, + radius: 10, + color: '#008F6D', + }, + textBackgroundStyle: { + padding: '10%', + color: '#0fA', + cornerRadius: { + topLeft: { + x: '20%', + y: '50%', + }, + topRight: { + x: '20%', + y: '50%', + }, + }, + }, + }, + }], + scale: 1, + quality: 100, + filename: 'test', + saveFormat: ImageFormat.png, + maxSize: 1000, +}; +ImageMarker.markText(options); + +``` + #### Text with shadow ##### API @@ -221,7 +288,7 @@ ImageMarker.markText(options); ##### Sample - + ##### Example @@ -273,7 +340,7 @@ Marker.markText(options); ##### Sample - + ##### Example @@ -326,9 +393,9 @@ Marker.markText({

- - - + + +

##### Example @@ -388,7 +455,7 @@ Marker.markText({ ##### Sample - + ##### Example @@ -421,7 +488,7 @@ Marker.markImage({ - + ##### Example @@ -461,8 +528,8 @@ Marker.markImage({

- - + +

##### Example @@ -540,7 +607,7 @@ Marker.markText({ ##### Sample - + ##### Example @@ -569,7 +636,7 @@ Marker.markImage({ ##### Sample - + ##### Example @@ -598,7 +665,7 @@ Marker.markImage({ ##### Sample - + ##### Example @@ -686,6 +753,11 @@ This library use [Fresco](https://github.com/facebook/fresco) to decode image on If you want to run the example locally, you can do the following: ```bash + +git clone git@github.com:JimmyDaddy/react-native-image-marker.git + +cd ./react-native-image-marker + # Android # Open an android emulator or connect a real device at first yarn example android diff --git a/android/src/main/java/com/jimmydaddy/imagemarker/ImageMarkerManager.kt b/android/src/main/java/com/jimmydaddy/imagemarker/ImageMarkerManager.kt index d2512b3c..63f2e191 100644 --- a/android/src/main/java/com/jimmydaddy/imagemarker/ImageMarkerManager.kt +++ b/android/src/main/java/com/jimmydaddy/imagemarker/ImageMarkerManager.kt @@ -84,8 +84,8 @@ class ImageMarkerManager(private val context: ReactApplicationContext) : ReactCo } else { canvas.drawBitmap( markerBitmap!!, - (Utils.parseSpreadValue(markOpts.x, width) ?: DEFAULT_MARGIN).toFloat(), - (Utils.parseSpreadValue(markOpts.y, height) ?: DEFAULT_MARGIN).toFloat(), + (Utils.parseSpreadValue(markOpts.x, width.toFloat()) ?: DEFAULT_MARGIN), + (Utils.parseSpreadValue(markOpts.y, height.toFloat()) ?: DEFAULT_MARGIN), markOpts.imageOption.applyStyle() ) } diff --git a/android/src/main/java/com/jimmydaddy/imagemarker/base/Constants.kt b/android/src/main/java/com/jimmydaddy/imagemarker/base/Constants.kt index 11f95dfd..c21b9473 100644 --- a/android/src/main/java/com/jimmydaddy/imagemarker/base/Constants.kt +++ b/android/src/main/java/com/jimmydaddy/imagemarker/base/Constants.kt @@ -15,5 +15,5 @@ object Constants { const val BASE64 = "base64" - const val DEFAULT_MARGIN = 20; + const val DEFAULT_MARGIN = 20f } diff --git a/android/src/main/java/com/jimmydaddy/imagemarker/base/CornerRadius.kt b/android/src/main/java/com/jimmydaddy/imagemarker/base/CornerRadius.kt new file mode 100644 index 00000000..3be37aff --- /dev/null +++ b/android/src/main/java/com/jimmydaddy/imagemarker/base/CornerRadius.kt @@ -0,0 +1,95 @@ +package com.jimmydaddy.imagemarker.base + +import com.facebook.react.bridge.ReadableMap + +import android.graphics.RectF + +data class CornerRadius(val opts: ReadableMap?) { + private var topLeft: Radius? = null + private var topRight: Radius? = null + private var bottomLeft: Radius? = null + private var bottomRight: Radius? = null + private var all: Radius? = null + + init { + + val iterator = opts?.entryIterator + + if (iterator != null) { + while (iterator.hasNext()) { + val entry = iterator.next() + val cornerRadius = entry.value + + when (entry.key) { + "topLeft" -> { + if (cornerRadius == null) break + topLeft = Radius(cornerRadius as ReadableMap?) + } + + "topRight" -> { + if (cornerRadius == null) break + topRight = Radius(cornerRadius as ReadableMap?) + } + + "bottomLeft" -> { + if (cornerRadius == null) break + bottomLeft = Radius(cornerRadius as ReadableMap?) + } + + "bottomRight" -> { + if (cornerRadius == null) break + bottomRight = Radius(cornerRadius as ReadableMap?) + } + + else -> { + if (cornerRadius == null) break + all = Radius(cornerRadius as ReadableMap?) + } + } + } + } + } + + fun radii(rect: RectF): FloatArray { + var mxRadius = 0f + var myRadius = 0f + + if (all != null) { + mxRadius = Utils.parseSpreadValue(all!!.x, rect.width()) + myRadius = Utils.parseSpreadValue(all!!.y, rect.height()) + } + + val radii = floatArrayOf( + mxRadius, // topLeftX + myRadius, // topLeftY + mxRadius, // topRightX + myRadius, // topRightY + mxRadius, // bottomRightX + myRadius, // bottomRightY + mxRadius, // bottomLeftX + myRadius // bottomLeftY + ) + + if (topLeft != null) { + radii[0] = Utils.parseSpreadValue(topLeft!!.x, rect.width()) + radii[1] = Utils.parseSpreadValue(topLeft!!.y, rect.height()) + } + + if (topRight != null) { + radii[2] = Utils.parseSpreadValue(topRight!!.x, rect.width()) + radii[3] = Utils.parseSpreadValue(topRight!!.y, rect.height()) + } + + if (bottomRight != null) { + radii[4] = Utils.parseSpreadValue(bottomRight!!.x, rect.width()) + radii[5] = Utils.parseSpreadValue(bottomRight!!.y, rect.height()) + } + + if (bottomLeft != null) { + radii[6] = Utils.parseSpreadValue(bottomLeft!!.x, rect.width()) + radii[7] = Utils.parseSpreadValue(bottomLeft!!.y, rect.height()) + } + + return radii + } +} diff --git a/android/src/main/java/com/jimmydaddy/imagemarker/base/ImageOptions.kt b/android/src/main/java/com/jimmydaddy/imagemarker/base/ImageOptions.kt index 6288303f..7546606d 100644 --- a/android/src/main/java/com/jimmydaddy/imagemarker/base/ImageOptions.kt +++ b/android/src/main/java/com/jimmydaddy/imagemarker/base/ImageOptions.kt @@ -9,8 +9,8 @@ import com.jimmydaddy.imagemarker.base.Constants.DEFAULT_ALPHA import com.jimmydaddy.imagemarker.base.Constants.DEFAULT_ROTATE import com.jimmydaddy.imagemarker.base.Constants.DEFAULT_SCALE -class ImageOptions(options: ReadableMap) { - var src: ReadableMap? +class ImageOptions(val options: ReadableMap) { + var src: ReadableMap? = options.getMap("src") var uri: String? @@ -20,7 +20,6 @@ class ImageOptions(options: ReadableMap) { private var alpha: Int init { - src = options.getMap("src") if (src == null) { throw MarkerError(ErrorCode.PARAMS_REQUIRED, "image is required") } diff --git a/android/src/main/java/com/jimmydaddy/imagemarker/base/Options.kt b/android/src/main/java/com/jimmydaddy/imagemarker/base/Options.kt index 5c34710f..62f14668 100644 --- a/android/src/main/java/com/jimmydaddy/imagemarker/base/Options.kt +++ b/android/src/main/java/com/jimmydaddy/imagemarker/base/Options.kt @@ -3,9 +3,11 @@ package com.jimmydaddy.imagemarker.base import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReadableMap -open class Options(options: ReadableMap) { +open class Options(val options: ReadableMap) { var backgroundImage: ImageOptions + var backgroundImageOpts = options.getMap("backgroundImage") + var quality: Int var filename: String? @@ -15,12 +17,11 @@ open class Options(options: ReadableMap) { var maxSize: Int init { - val backgroundImageOpts = options.getMap("backgroundImage") - ?: throw MarkerError( - ErrorCode.PARAMS_REQUIRED, - "backgroundImage is required" - ) - backgroundImage = ImageOptions(backgroundImageOpts) + this.backgroundImageOpts ?: throw MarkerError( + ErrorCode.PARAMS_REQUIRED, + "backgroundImage is required" + ) + backgroundImage = ImageOptions(this.backgroundImageOpts!!) quality = if (options.hasKey("quality")) options.getInt("quality") else 100 maxSize = if (options.hasKey("maxSize")) options.getInt("maxSize") else 2048 filename = options.getString("filename") diff --git a/android/src/main/java/com/jimmydaddy/imagemarker/base/Padding.kt b/android/src/main/java/com/jimmydaddy/imagemarker/base/Padding.kt index 9fc7803f..7ae406a2 100644 --- a/android/src/main/java/com/jimmydaddy/imagemarker/base/Padding.kt +++ b/android/src/main/java/com/jimmydaddy/imagemarker/base/Padding.kt @@ -9,10 +9,10 @@ open class Padding(paddingData: ReadableMap?) { private var paddingRight: String = "0" init { - var topValue: String = "0" - var leftValue: String = "0" - var bottomValue: String = "0" - var rightValue: String = "0" + var topValue = "0" + var leftValue = "0" + var bottomValue = "0" + var rightValue = "0" val iterator = paddingData?.entryIterator @@ -147,10 +147,10 @@ open class Padding(paddingData: ReadableMap?) { } fun toEdgeInsets(width: Int, height: Int): MarkerInsets { - val topValue = Utils.parseSpreadValue(paddingTop, relativeTo = height) ?: 0f - val leftValue = Utils.parseSpreadValue(paddingLeft, relativeTo = width) ?: 0f - val bottomValue = Utils.parseSpreadValue(paddingBottom, relativeTo = height) ?: 0f - val rightValue = Utils.parseSpreadValue(paddingRight, relativeTo = width) ?: 0f + val topValue = Utils.parseSpreadValue(paddingTop, relativeTo = height.toFloat()) ?: 0f + val leftValue = Utils.parseSpreadValue(paddingLeft, relativeTo = width.toFloat()) ?: 0f + val bottomValue = Utils.parseSpreadValue(paddingBottom, relativeTo = height.toFloat()) ?: 0f + val rightValue = Utils.parseSpreadValue(paddingRight, relativeTo = width.toFloat()) ?: 0f return MarkerInsets(topValue.toInt(), leftValue.toInt(), bottomValue.toInt(), rightValue.toInt()) } } diff --git a/android/src/main/java/com/jimmydaddy/imagemarker/base/Position.kt b/android/src/main/java/com/jimmydaddy/imagemarker/base/Position.kt index 04cdec0c..b7131a9a 100644 --- a/android/src/main/java/com/jimmydaddy/imagemarker/base/Position.kt +++ b/android/src/main/java/com/jimmydaddy/imagemarker/base/Position.kt @@ -3,7 +3,7 @@ package com.jimmydaddy.imagemarker.base /** * Created by jimmydaddy on 2017/9/23. */ -class Position(var x: Float, var y: Float) { +data class Position(var x: Float, var y: Float) { companion object { fun getTextPosition( diff --git a/android/src/main/java/com/jimmydaddy/imagemarker/base/Radius.kt b/android/src/main/java/com/jimmydaddy/imagemarker/base/Radius.kt new file mode 100644 index 00000000..62c6473e --- /dev/null +++ b/android/src/main/java/com/jimmydaddy/imagemarker/base/Radius.kt @@ -0,0 +1,14 @@ +package com.jimmydaddy.imagemarker.base + +import com.facebook.react.bridge.ReadableMap + +data class Radius(val options: ReadableMap?) { + + var x: String = "0" + var y: String = "0" + + init { + x = Utils.handleDynamicToString(options?.getDynamic("x")) + y = Utils.handleDynamicToString(options?.getDynamic("y")) + } +} diff --git a/android/src/main/java/com/jimmydaddy/imagemarker/base/ShadowLayerStyle.kt b/android/src/main/java/com/jimmydaddy/imagemarker/base/ShadowLayerStyle.kt index b1dee411..0f61ecb9 100644 --- a/android/src/main/java/com/jimmydaddy/imagemarker/base/ShadowLayerStyle.kt +++ b/android/src/main/java/com/jimmydaddy/imagemarker/base/ShadowLayerStyle.kt @@ -7,7 +7,7 @@ import com.facebook.react.bridge.ReadableMap /** * Created by jimmydaddy on 2019/2/25. */ -class ShadowLayerStyle(readableMap: ReadableMap?) { +data class ShadowLayerStyle(val readableMap: ReadableMap?) { var radius = 0f var dx = 0f var dy = 0f diff --git a/android/src/main/java/com/jimmydaddy/imagemarker/base/TextBackgroundStyle.kt b/android/src/main/java/com/jimmydaddy/imagemarker/base/TextBackgroundStyle.kt index c0b871f7..90aee5a5 100644 --- a/android/src/main/java/com/jimmydaddy/imagemarker/base/TextBackgroundStyle.kt +++ b/android/src/main/java/com/jimmydaddy/imagemarker/base/TextBackgroundStyle.kt @@ -4,15 +4,17 @@ import android.graphics.Color import android.util.Log import com.facebook.react.bridge.ReadableMap -class TextBackgroundStyle(readableMap: ReadableMap?): Padding(readableMap) { +data class TextBackgroundStyle(val readableMap: ReadableMap?): Padding(readableMap) { var type: String? = "" var color = Color.TRANSPARENT + var cornerRadius: CornerRadius? = null init { if (null != readableMap) { try { type = readableMap.getString("type") setColor(readableMap.getString("color")) + cornerRadius = readableMap.getMap("cornerRadius")?.let { CornerRadius(it) }!! } catch (e: Exception) { Log.d(Utils.TAG, "Unknown text background options ", e) } diff --git a/android/src/main/java/com/jimmydaddy/imagemarker/base/TextOptions.kt b/android/src/main/java/com/jimmydaddy/imagemarker/base/TextOptions.kt index 0fe03bbd..5a79a719 100644 --- a/android/src/main/java/com/jimmydaddy/imagemarker/base/TextOptions.kt +++ b/android/src/main/java/com/jimmydaddy/imagemarker/base/TextOptions.kt @@ -3,7 +3,7 @@ package com.jimmydaddy.imagemarker.base import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint -import android.graphics.Rect +import android.graphics.Path import android.graphics.RectF import android.graphics.Typeface import android.os.Build @@ -18,15 +18,14 @@ import com.jimmydaddy.imagemarker.base.Constants.DEFAULT_MARGIN import kotlin.math.ceil @Suppress("DEPRECATION") -class TextOptions(options: ReadableMap) { - private var text: String? +data class TextOptions(val options: ReadableMap) { + private var text: String? = options.getString("text") private var x: String? private var y: String? private var positionEnum: PositionEnum? private var style: TextStyle init { - text = options.getString("text") if (text == null) { throw MarkerError(ErrorCode.PARAMS_REQUIRED, "mark text is required") } @@ -126,10 +125,10 @@ class TextOptions(options: ReadableMap) { ) } else { if (null != x) { - position.x = (Utils.parseSpreadValue(x, maxWidth) ?: margin) as Float + position.x = (Utils.parseSpreadValue(x, maxWidth.toFloat()) ?: margin) as Float } if (null != y) { - position.y = (Utils.parseSpreadValue(y, maxHeight) ?: margin) as Float + position.y = (Utils.parseSpreadValue(y, maxHeight.toFloat()) ?: margin) as Float } } val x = position.x @@ -145,21 +144,29 @@ class TextOptions(options: ReadableMap) { paint.style = Paint.Style.FILL paint.color = style.textBackgroundStyle!!.color val bgInsets = style.textBackgroundStyle!!.toEdgeInsets(maxWidth, maxHeight) - var bgRect = Rect((x - bgInsets.left).toInt(), (y - bgInsets.top).toInt(), (x + textWidth + bgInsets.right).toInt(), (y + textHeight + bgInsets.bottom).toInt()) + var bgRect = RectF(x - bgInsets.left, y - bgInsets.top, x + textWidth + bgInsets.right, y + textHeight + bgInsets.bottom) when (style.textBackgroundStyle!!.type) { "stretchX" -> { - bgRect = Rect(0, (y - bgInsets.top).toInt(), maxWidth, - (y + textHeight + bgInsets.bottom).toInt() + bgRect = RectF(0f, y - bgInsets.top, maxWidth.toFloat(), + y + textHeight + bgInsets.bottom ) } "stretchY" -> { - bgRect = Rect((x - bgInsets.left).toInt(), 0, - (x + textWidth + bgInsets.right).toInt(), maxHeight) + bgRect = RectF(x - bgInsets.left, 0f, + x + textWidth + bgInsets.right, maxHeight.toFloat()) } } - canvas.drawRect(bgRect, paint) + if (style.textBackgroundStyle!!.cornerRadius != null) { + val path = Path() + + path.addRoundRect(bgRect, style.textBackgroundStyle!!.cornerRadius!!.radii(bgRect), Path.Direction.CW); + + canvas.drawPath(path, paint); + } else { + canvas.drawRect(bgRect, paint) + } } canvas.restore() canvas.save() diff --git a/android/src/main/java/com/jimmydaddy/imagemarker/base/TextStyle.kt b/android/src/main/java/com/jimmydaddy/imagemarker/base/TextStyle.kt index 73169b88..cefd1306 100644 --- a/android/src/main/java/com/jimmydaddy/imagemarker/base/TextStyle.kt +++ b/android/src/main/java/com/jimmydaddy/imagemarker/base/TextStyle.kt @@ -4,38 +4,27 @@ import android.graphics.Paint.Align import com.facebook.react.bridge.ReadableMap import com.jimmydaddy.imagemarker.base.Constants.DEFAULT_FONT_SIZE -class TextStyle(options: ReadableMap?) { - var color: String? - var fontName: String? - var fontSize: Int +data class TextStyle(val options: ReadableMap?) { + var color: String? = if (null != options!!.getString("color")) options.getString("color") else null + var fontName: String? = if (null != options?.getString("fontName")) options.getString("fontName") else null + var fontSize: Int = if (options?.hasKey("fontSize") == true) options.getInt("fontSize") else DEFAULT_FONT_SIZE var shadowLayerStyle: ShadowLayerStyle? var textBackgroundStyle: TextBackgroundStyle? - var underline: Boolean - var skewX: Float? - var strikeThrough: Boolean + var underline: Boolean = if (options?.hasKey("underline") == true) options.getBoolean("underline") else false + var skewX: Float? = if (options?.hasKey("skewX") == true) options?.getDouble("skewX")?.toFloat() else 0f + var strikeThrough: Boolean = if (options?.hasKey("strikeThrough") == true) options.getBoolean("strikeThrough") else false var textAlign: Align - var italic: Boolean - var bold: Boolean - var rotate: Int + var italic: Boolean = if (options?.hasKey("italic") == true) options.getBoolean("italic") else false + var bold: Boolean = if (options?.hasKey("bold") == true) options.getBoolean("bold") else false + var rotate: Int = if (options?.hasKey("rotate") == true) options.getInt("rotate") else 0 init { - color = if (null != options!!.getString("color")) options.getString("color") else null - fontSize = if (options.hasKey("fontSize")) options.getInt("fontSize") else DEFAULT_FONT_SIZE - fontName = - if (null != options.getString("fontName")) options.getString("fontName") else null - skewX = if (options.hasKey("skewX")) options.getDouble("skewX").toFloat() else 0f - rotate = if (options.hasKey("rotate")) options.getInt("rotate") else 0 - underline = if (options.hasKey("underline")) options.getBoolean("underline") else false - strikeThrough = - if (options.hasKey("strikeThrough")) options.getBoolean("strikeThrough") else false - italic = if (options.hasKey("italic")) options.getBoolean("italic") else false - bold = if (options.hasKey("bold")) options.getBoolean("bold") else false - val myShadowStyle = options.getMap("shadowStyle") + val myShadowStyle = options?.getMap("shadowStyle") shadowLayerStyle = myShadowStyle?.let { ShadowLayerStyle(it) } - val myTextBackgroundStyle = options.getMap("textBackgroundStyle") + val myTextBackgroundStyle = options?.getMap("textBackgroundStyle") textBackgroundStyle = myTextBackgroundStyle?.let { TextBackgroundStyle(it) } textAlign = Align.LEFT - if (options.hasKey("textAlign")) { + if (options?.hasKey("textAlign") == true) { textAlign = when (options.getString("textAlign")) { "center" -> Align.CENTER "right" -> Align.RIGHT diff --git a/android/src/main/java/com/jimmydaddy/imagemarker/base/Utils.kt b/android/src/main/java/com/jimmydaddy/imagemarker/base/Utils.kt index ed3fec0e..9c81ce66 100644 --- a/android/src/main/java/com/jimmydaddy/imagemarker/base/Utils.kt +++ b/android/src/main/java/com/jimmydaddy/imagemarker/base/Utils.kt @@ -149,8 +149,8 @@ class Utils { return pattern.containsMatchIn(str) } - fun parseSpreadValue(v: String?, relativeTo: Int): Float? { - if (v == null) return null + fun parseSpreadValue(v: String?, relativeTo: Float): Float { + if (v == null) return 0f return if (v.endsWith("%")) { val percent = v.dropLast(1).toFloatOrNull()?.div(100) ?: 0f relativeTo * percent diff --git a/android/src/main/java/com/jimmydaddy/imagemarker/base/WatermarkImageOptions.kt b/android/src/main/java/com/jimmydaddy/imagemarker/base/WatermarkImageOptions.kt index b8cb323e..57d7d68b 100644 --- a/android/src/main/java/com/jimmydaddy/imagemarker/base/WatermarkImageOptions.kt +++ b/android/src/main/java/com/jimmydaddy/imagemarker/base/WatermarkImageOptions.kt @@ -2,14 +2,14 @@ package com.jimmydaddy.imagemarker.base import com.facebook.react.bridge.ReadableMap -class WatermarkImageOptions { +data class WatermarkImageOptions(val options: ReadableMap?) { var imageOption: ImageOptions var x: String? var y: String? var positionEnum: PositionEnum? - constructor(options: ReadableMap) { - imageOption = ImageOptions(options); + init { + imageOption = options?.let { ImageOptions(it) }!! val positionOptions = if (null != options.getMap("position")) options.getMap("position") else null x = if (positionOptions!!.hasKey("X")) positionOptions.getDynamic("X").toString() else null @@ -20,7 +20,7 @@ class WatermarkImageOptions { ) else null } - constructor(watermarkImage: ImageOptions, X: String?, Y: String?, position: PositionEnum?) { + constructor(watermarkImage: ImageOptions, X: String?, Y: String?, position: PositionEnum?) : this(null) { imageOption = watermarkImage this.x = X this.y = Y diff --git a/asset/AndroidMarker.gif b/assets/AndroidMarker.gif similarity index 100% rename from asset/AndroidMarker.gif rename to assets/AndroidMarker.gif diff --git a/asset/IOSMarker.gif b/assets/IOSMarker.gif similarity index 100% rename from asset/IOSMarker.gif rename to assets/IOSMarker.gif diff --git a/asset/alphabgonly.png b/assets/alphabgonly.png similarity index 100% rename from asset/alphabgonly.png rename to assets/alphabgonly.png diff --git a/asset/alphicononly.png b/assets/alphicononly.png similarity index 100% rename from asset/alphicononly.png rename to assets/alphicononly.png diff --git a/asset/icon.png b/assets/icon.png similarity index 100% rename from asset/icon.png rename to assets/icon.png diff --git a/asset/imagewatermark.png b/assets/imagewatermark.png similarity index 100% rename from asset/imagewatermark.png rename to assets/imagewatermark.png diff --git a/asset/multiple_icon_markers.png b/assets/multiple_icon_markers.png similarity index 100% rename from asset/multiple_icon_markers.png rename to assets/multiple_icon_markers.png diff --git a/asset/multipletexts.png b/assets/multipletexts.png similarity index 100% rename from asset/multipletexts.png rename to assets/multipletexts.png diff --git a/asset/rotatebg.png b/assets/rotatebg.png similarity index 100% rename from asset/rotatebg.png rename to assets/rotatebg.png diff --git a/asset/rotateicon.png b/assets/rotateicon.png similarity index 100% rename from asset/rotateicon.png rename to assets/rotateicon.png diff --git a/asset/rotateimageicon.png b/assets/rotateimageicon.png similarity index 100% rename from asset/rotateimageicon.png rename to assets/rotateimageicon.png diff --git a/asset/rotatetexts.png b/assets/rotatetexts.png similarity index 100% rename from asset/rotatetexts.png rename to assets/rotatetexts.png diff --git a/asset/rotatetexts_1.png b/assets/rotatetexts_1.png similarity index 100% rename from asset/rotatetexts_1.png rename to assets/rotatetexts_1.png diff --git a/asset/sample1.png b/assets/sample1.png similarity index 100% rename from asset/sample1.png rename to assets/sample1.png diff --git a/asset/sample2.png b/assets/sample2.png similarity index 100% rename from asset/sample2.png rename to assets/sample2.png diff --git a/asset/shadow.png b/assets/shadow.png similarity index 100% rename from asset/shadow.png rename to assets/shadow.png diff --git a/asset/shadow_bg_fit.png b/assets/shadow_bg_fit.png similarity index 100% rename from asset/shadow_bg_fit.png rename to assets/shadow_bg_fit.png diff --git a/asset/shadow_bg_sx.png b/assets/shadow_bg_sx.png similarity index 100% rename from asset/shadow_bg_sx.png rename to assets/shadow_bg_sx.png diff --git a/asset/shadow_bg_sy.png b/assets/shadow_bg_sy.png similarity index 100% rename from asset/shadow_bg_sy.png rename to assets/shadow_bg_sy.png diff --git a/assets/textbgcornerradius.png b/assets/textbgcornerradius.png new file mode 100644 index 00000000..2a7e1c9f Binary files /dev/null and b/assets/textbgcornerradius.png differ diff --git a/asset/textswihoutbg.png b/assets/textswihoutbg.png similarity index 100% rename from asset/textswihoutbg.png rename to assets/textswihoutbg.png diff --git a/docs/latest/index.html b/docs/latest/index.html index c9c0f3ad..3b38b9d6 100644 --- a/docs/latest/index.html +++ b/docs/latest/index.html @@ -14,7 +14,7 @@

image marker for rn

- react native image marker Logo + react native image marker Logo

react native image marker

Add text or icon watermarks to images
@@ -45,8 +45,8 @@
Add text or icon watermarks to images
  • Compatible with both Android and iOS
  • -

    Sample

    - +

    Sample

    +

    Usage

    Text background

    Text background fit

    API

    TextBackgroundType.none

    -
    Sample
    +
    Sample
    Example
    import Marker, { Position, TextBackgroundType } from "react-native-image-marker"
    ···
    const options = {
    // background image
    backgroundImage: {
    src: require('./images/test.jpg'),
    scale: 1,
    },
    watermarkTexts: [{
    text: 'text marker \n multline text',
    positionOptions: {
    position: Position.topLeft,
    },
    style: {
    color: '#ff00ff',
    fontSize: 30,
    fontName: 'Arial',
    shadowStyle: {
    dx: 10,
    dy: 10,
    radius: 10,
    color: '#008F6D',
    },
    textBackgroundStyle: {
    padding: '10% 10%',
    type: TextBackgroundType.none,
    color: '#0FFF00',
    },
    },
    }],
    scale: 1,
    quality: 100,
    filename: 'test',
    saveFormat: ImageFormat.png,
    maxSize: 1000,
    };
    Marker.markText(options);

    Text background stretchX

    API

    TextBackgroundType.stretchX

    -
    Sample
    +
    Sample
    Example
    import Marker, { Position, TextBackgroundType } from "react-native-image-marker"
    ···
    const options = {
    // background image
    backgroundImage: {
    src: require('./images/test.jpg'),
    scale: 1,
    },
    watermarkTexts: [{
    text: 'text marker \n multline text',
    positionOptions: {
    position: Position.topLeft,
    },
    style: {
    color: '#FC0700',
    fontSize: 30,
    fontName: 'Arial',
    shadowStyle: {
    dx: 10,
    dy: 10,
    radius: 10,
    color: '#008F6D',
    },
    textBackgroundStyle: {
    padding: '10% 10%',
    type: TextBackgroundType.stretchX,
    color: '#0FFF00',
    },
    },
    }],
    scale: 1,
    quality: 100,
    filename: 'test',
    saveFormat: ImageFormat.png,
    maxSize: 1000,
    };
    Marker.markText(options);

    Text background stretchY

    API

    TextBackgroundType.stretchY

    -
    Sample
    +
    Sample
    Example
    import Marker, { Position, TextBackgroundType } from "react-native-image-marker"
    ···
    const options = {
    // background image
    backgroundImage: {
    src: require('./images/test.jpg'),
    scale: 1,
    },
    watermarkTexts: [{
    text: 'text marker \n multline text',
    positionOptions: {
    position: Position.topLeft,
    },
    style: {
    color: '#FC0700',
    fontSize: 30,
    fontName: 'Arial',
    shadowStyle: {
    dx: 10,
    dy: 10,
    radius: 10,
    color: '#008F6D',
    },
    textBackgroundStyle: {
    padding: '10% 10%',
    type: TextBackgroundType.stretchY,
    color: '#0FFF00',
    },
    },
    }],
    scale: 1,
    quality: 100,
    filename: 'test',
    saveFormat: ImageFormat.png,
    maxSize: 1000,
    };
    ImageMarker.markText(options);

    Text with shadow

    API

    ShadowLayerStyle

    -
    Sample
    +
    Sample
    Example
    import Marker, { Position, TextBackgroundType } from "react-native-image-marker"
    ···
    const options = {
    // background image
    backgroundImage: {
    src: require('./images/test.jpg'),
    scale: 1,
    },
    watermarkTexts: [{
    text: 'text marker \n multline text',
    positionOptions: {
    position: Position.topLeft,
    },
    style: {
    color: '#F4F50A',
    fontSize: 30,
    fontName: 'Arial',
    shadowStyle: {
    dx: 10,
    dy: 10,
    radius: 10,
    color: '#6450B0',
    },
    },
    }],
    scale: 1,
    quality: 100,
    filename: 'test',
    saveFormat: ImageFormat.png,
    maxSize: 1000,
    };
    Marker.markText(options);

    Multiple text watermarks

    API

    markImage

    -
    Sample
    +
    Sample
    Example
    import Marker, { Position, TextBackgroundType } from "react-native-image-marker"
    ···
    Marker.markText({
    backgroundImage: {
    src: require('./images/test.jpg'),
    scale: 1,
    },
    waterMarkTexts: [{
    text: 'hello world \n 你好',
    positionOptions: {
    position: Position.topLeft,
    },
    style: {
    color: '#BB3B20',
    fontSize: 30,
    fontName: 'Arial',
    textBackgroundStyle: {
    padding: '10% 10%',
    color: '#0FFF00',
    },
    },
    }, {
    text: 'text marker normal',
    positionOptions: {
    position: Position.topRight,
    },
    style: {
    color: '#6450B0',
    fontSize: 30,
    fontName: 'Arial',
    textBackgroundStyle: {
    padding: '10% 10%',
    color: '#02FBBE',
    },
    },
    }],
    })

    Text rotation

    Sample

    - - - + + +

    Example
    import Marker, { Position, TextBackgroundType } from "react-native-image-marker"
    ···
    Marker.markText({
    backgroundImage: {
    src: require('./images/test.jpg'),
    scale: 1,
    rotate: 30,
    },
    waterMarkTexts: [{
    text: 'hello world \n 你好',
    positionOptions: {
    position: Position.topLeft,
    },
    style: {
    color: '#FFFF00',
    fontSize: 30,
    fontName: 'Arial',
    rotate: 30,
    textBackgroundStyle: {
    padding: '10% 10%',
    color: '#02B96B',
    },
    strikeThrough: true,
    underline: true,
    },
    }, {
    text: 'text marker normal',
    positionOptions: {
    position: Position.center,
    },
    style: {
    color: '#FFFF00',
    fontSize: 30,
    fontName: 'Arial',
    rotate: 30,
    textBackgroundStyle: {
    padding: '10% 10%',
    color: '#0FFF00',
    },
    strikeThrough: true,
    underline: true,
    },
    }],
    })
    -

    Icon watermarks

    Sample
    +

    Icon watermarks

    Sample
    Example
    import Marker, { Position, TextBackgroundType } from "react-native-image-marker"
    ···
    Marker.markImage({
    backgroundImage: {
    src: require('./images/test.jpg'),
    scale: 1,
    },
    watermarkImages: [{
    src: require('./images/watermark.png'),
    position: {
    position: Position.topLeft,
    },
    }],
    })

    Multiple icon watermarks

    Note: require Android >= N, iOS >= iOS 13

    -
    Sample
    +
    Sample
    Example
    import Marker, { Position, TextBackgroundType } from "react-native-image-marker"
    ···
    Marker.markImage({
    backgroundImage: {
    src: require('./images/test.jpg'),
    scale: 1,
    },
    watermarkImages: [{
    src: require('./images/watermark.png'),
    position: {
    position: Position.topLeft,
    },
    }, {
    src: require('./images/watermark1.png'),
    position: {
    position: Position.topRight,
    },
    }, {
    src: require('./images/watermark2.png'),
    position: {
    position: Position.bottomCenter,
    },
    }],
    })

    Background rotation

    Sample

    - - + +

    Example
    import Marker, { Position, TextBackgroundType } from "react-native-image-marker"
    ···
    Marker.markImage({
    backgroundImage: {
    src: require('./images/test.jpg'),
    scale: 1,
    rotate: 30,
    },
    watermarkImages: [{
    src: require('./images/watermark.png'),
    position: {
    position: Position.topLeft,
    },
    }],
    });

    Marker.markText({
    backgroundImage: {
    src: require('./images/test.jpg'),
    scale: 1,
    rotate: 30,
    },
    watermarkTexts: [{
    text: 'hello world \n 你好',
    positionOptions: {
    position: Position.topLeft,
    },
    style: {
    color: '#FFFF00',
    fontSize: 30,
    fontName: 'Arial',
    rotate: 30,
    textBackgroundStyle: {
    padding: '10% 10%',
    color: '#02B96B',
    },
    shadowStyle: {
    dx: 10,
    dy: 10,
    radius: 10,
    color: '#008F6D',
    },
    strikeThrough: true,
    underline: true,
    },
    }, {
    text: 'hello world \n 你好',
    positionOptions: {
    position: Position.center,
    },
    style: {
    color: '#FFFF00',
    fontSize: 30,
    fontName: 'Arial',
    textBackgroundStyle: {
    padding: '10% 10%',
    color: '#0FFF00',
    },
    strikeThrough: true,
    underline: true,
    },
    }],
    })
    -

    Icon rotation

    Sample
    +

    Icon rotation

    Sample
    Example
    import Marker, { Position, TextBackgroundType } from "react-native-image-marker"
    ···
    Marker.markImage({
    backgroundImage: {
    src: require('./images/test.jpg'),
    scale: 1,
    },
    watermarkImages: [{
    src: require('./images/watermark.png'),
    position: {
    position: Position.topLeft,
    },
    rotate: 30,
    }],
    });
    -

    Transparent background

    Sample
    +

    Transparent background

    Sample
    Example
    import Marker, { Position, TextBackgroundType } from "react-native-image-marker"
    ···
    Marker.markImage({
    backgroundImage: {
    src: require('./images/test.jpg'),
    scale: 1,
    alpha: 0.5,
    },
    watermarkImages: [{
    src: require('./images/watermark.png'),
    position: {
    position: Position.topLeft,
    },
    }],
    });
    -

    Transparent icon

    Sample
    +

    Transparent icon

    Sample
    Example
    import Marker, { Position, TextBackgroundType } from "react-native-image-marker"
    ···
    Marker.markImage({
    backgroundImage: {
    src: require('./images/test.jpg'),
    scale: 1,
    },
    watermarkImages: [{
    src: require('./images/watermark.png'),
    position: {
    position: Position.topLeft,
    },
    alpha: 0.5,
    }],
    });
    diff --git a/docs/v1.0.x/index.html b/docs/v1.0.x/index.html index 49cd1e9e..fbc179d0 100644 --- a/docs/v1.0.x/index.html +++ b/docs/v1.0.x/index.html @@ -34,22 +34,22 @@

    image marker for rn v1.0.x

  • Compatible with both Android and iOS
  • sample

    - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + +

    Installation