diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f102041..35bc9a2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,10 +1,10 @@ name: CI -on: +on: pull_request: types: [opened, synchronize, reopened] workflow_dispatch: -concurrency: +concurrency: group: ${{ github.workflow }}-${{ github.head_ref }} cancel-in-progress: true @@ -43,7 +43,7 @@ jobs: ruby-version: 2.7 bundler-cache: true - - name: Setup node 16 + - name: Setup node if: steps.verify-dev-changed-files.outputs.any_changed == 'true' uses: actions/setup-node@v3 with: @@ -108,7 +108,7 @@ jobs: ruby-version: 2.7 bundler-cache: true - - name: Setup node 16 + - name: Setup node uses: actions/setup-node@v3 if: steps.verify-android-changed-files.outputs.any_changed == 'true' with: @@ -120,7 +120,7 @@ jobs: with: distribution: 'zulu' java-version: 17 - + - name: Install Gradle dependencies if: steps.cache-gradle.outputs.cache-hit != 'true' && steps.verify-android-changed-files.outputs.any_changed == 'true' run: | @@ -129,7 +129,7 @@ jobs: - name: Run unit tests if: steps.verify-android-changed-files.outputs.any_changed == 'true' - run: | + run: | cd example/android ./gradlew test --stacktrace @@ -154,7 +154,7 @@ jobs: name: Android Test strategy: matrix: - api-level: [24, 25, 29, 30, 31] + api-level: [24, 30, 31] target: [default] steps: - name: Checkout the code @@ -201,7 +201,7 @@ jobs: ruby-version: 2.7 bundler-cache: true - - name: Setup node 16 + - name: Setup node uses: actions/setup-node@v3 if: steps.verify-android-changed-files.outputs.any_changed == 'true' with: @@ -265,7 +265,7 @@ jobs: example/node_modules key: ${{ runner.os }}-nodeModules-${{ hashFiles('package.json') }}-${{ hashFiles('example/package.json') }} fail-on-cache-miss: true - + - name: Cache Pods id: cache-pods uses: actions/cache@v3 @@ -280,12 +280,12 @@ jobs: with: ruby-version: 2.7 bundler-cache: true - + - name: Install Cocoapods if: steps.verify-iOS-changed-files.outputs.any_changed == 'true' run: gem install cocoapods -v ${{ matrix.cocoapods }} - - name: Setup node 16 + - name: Setup node if: steps.verify-iOS-changed-files.outputs.any_changed == 'true' uses: actions/setup-node@v3 with: @@ -304,13 +304,13 @@ jobs: - name: Build if: steps.verify-iOS-changed-files.outputs.any_changed == 'true' - run: | + run: | cd example/ios xcodebuild -workspace ImageMarkerExample.xcworkspace -scheme ImageMarkerExample -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 12' | xcpretty - name: Test if: steps.verify-iOS-changed-files.outputs.any_changed == 'true' - run: | + run: | cd example/ios xcodebuild -workspace ImageMarkerExample.xcworkspace -scheme ImageMarkerExample -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 12' test | xcpretty diff --git a/CHANGELOG.md b/CHANGELOG.md index ff9efdd..bfb7b86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ +## [1.2.4](https://github.com/JimmyDaddy/react-native-image-marker/compare/v1.2.3...v1.2.4) (2024-01-24) + + +### Bug Fixes + +* set the font size without considering the screen density ([3df1080](https://github.com/JimmyDaddy/react-native-image-marker/commit/3df10801fceb3bbef894af4089074ed6a3bd64e7)) + + +### Features + +* replace positionOptions to postions ([482198f](https://github.com/JimmyDaddy/react-native-image-marker/commit/482198f55f1c18f7aecdbbcdaaa9f6a2ef35b119)) + ## [1.2.3](https://github.com/JimmyDaddy/react-native-image-marker/compare/v1.2.2...v1.2.3) (2024-01-22) 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 9c7ad0b..7a6d03b 100644 --- a/android/src/main/java/com/jimmydaddy/imagemarker/base/TextOptions.kt +++ b/android/src/main/java/com/jimmydaddy/imagemarker/base/TextOptions.kt @@ -31,7 +31,7 @@ data class TextOptions(val options: ReadableMap) { throw MarkerError(ErrorCode.PARAMS_REQUIRED, "mark text is required") } val positionOptions = - if (null != options.getMap("positionOptions")) options.getMap("positionOptions") else null + if (null != options.getMap("position")) options.getMap("position") else null x = if (positionOptions!!.hasKey("X")) Utils.handleDynamicToString(positionOptions.getDynamic("X")) else null y = if (positionOptions.hasKey("Y")) Utils.handleDynamicToString(positionOptions.getDynamic("Y")) else null positionEnum = @@ -69,11 +69,12 @@ data class TextOptions(val options: ReadableMap) { Typeface.DEFAULT } } - val textSize = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_SP, - style.fontSize, - context.resources.displayMetrics - ) +// val textSize = TypedValue.applyDimension( +// TypedValue.COMPLEX_UNIT_SP, +// style.fontSize, +// context.resources.displayMetrics +// ) + val textSize = style.fontSize textPaint.isAntiAlias = true textPaint.textSize = textSize Log.i(Constants.IMAGE_MARKER_TAG, "textSize: " + textSize + " fontSize: " + style.fontSize + " displayMetrics: " + context.resources.displayMetrics) @@ -121,7 +122,7 @@ data class TextOptions(val options: ReadableMap) { ).toInt() } val margin = DEFAULT_MARGIN - var position = Position(margin.toFloat(), margin.toFloat()) + var position = Position(margin, margin) if (positionEnum != null) { position = Position.getTextPosition( positionEnum, @@ -168,9 +169,9 @@ data class TextOptions(val options: ReadableMap) { if (style.textBackgroundStyle!!.cornerRadius != null) { val path = Path() - path.addRoundRect(bgRect, style.textBackgroundStyle!!.cornerRadius!!.radii(bgRect), Path.Direction.CW); + path.addRoundRect(bgRect, style.textBackgroundStyle!!.cornerRadius!!.radii(bgRect), Path.Direction.CW) - canvas.drawPath(path, paint); + canvas.drawPath(path, paint) } else { canvas.drawRect(bgRect, paint) } @@ -179,6 +180,7 @@ data class TextOptions(val options: ReadableMap) { Paint.Align.RIGHT -> x + textWidth Paint.Align.CENTER -> x + textWidth / 2 Paint.Align.LEFT -> x + else -> x } canvas.translate(textX, y) textLayout.draw(canvas) 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 cd2a1ce..4dd5964 100644 --- a/android/src/main/java/com/jimmydaddy/imagemarker/base/TextStyle.kt +++ b/android/src/main/java/com/jimmydaddy/imagemarker/base/TextStyle.kt @@ -11,7 +11,7 @@ data class TextStyle(val options: ReadableMap?) { var shadowLayerStyle: ShadowLayerStyle? var textBackgroundStyle: TextBackgroundStyle? 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 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 = if (options?.hasKey("italic") == true) options.getBoolean("italic") else false diff --git a/example/src/App.tsx b/example/src/App.tsx index a54d134..fcefa20 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -291,8 +291,11 @@ function useViewModel() { useModal: true, }, (buttonIndex) => { - if (buttonIndex === cancelButtonIndex || buttonIndex == null) return; - else setBackgroundFormat(options[buttonIndex] as any); + if (buttonIndex === cancelButtonIndex || buttonIndex == null) { + return; + } else { + setBackgroundFormat(options[buttonIndex] as any); + } } ); } @@ -309,8 +312,11 @@ function useViewModel() { useModal: true, }, (buttonIndex) => { - if (buttonIndex === cancelButtonIndex || buttonIndex == null) return; - else setWaterMarkType(options[buttonIndex] as any); + if (buttonIndex === cancelButtonIndex || buttonIndex == null) { + return; + } else { + setWaterMarkType(options[buttonIndex] as any); + } } ); } @@ -332,8 +338,11 @@ function useViewModel() { useModal: true, }, (buttonIndex) => { - if (buttonIndex === cancelButtonIndex || buttonIndex == null) return; - else setSaveFormat(options[buttonIndex] as any); + if (buttonIndex === cancelButtonIndex || buttonIndex == null) { + return; + } else { + setSaveFormat(options[buttonIndex] as any); + } } ); } @@ -359,8 +368,9 @@ function useViewModel() { useModal: true, }, (buttonIndex) => { - if (buttonIndex === cancelButtonIndex || buttonIndex == null) return; - else { + if (buttonIndex === cancelButtonIndex || buttonIndex == null) { + return; + } else { setPosition(options[buttonIndex] as any); } } @@ -384,8 +394,9 @@ function useViewModel() { useModal: true, }, (buttonIndex) => { - if (buttonIndex === cancelButtonIndex || buttonIndex == null) return; - else { + if (buttonIndex === cancelButtonIndex || buttonIndex == null) { + return; + } else { setTextBgStretch(options[buttonIndex] as any); } } @@ -404,8 +415,9 @@ function useViewModel() { useModal: true, }, (buttonIndex) => { - if (buttonIndex === cancelButtonIndex || buttonIndex == null) return; - else { + if (buttonIndex === cancelButtonIndex || buttonIndex == null) { + return; + } else { setTextAlign(options[buttonIndex] as any); } } @@ -514,7 +526,7 @@ function useViewModel() { }, }, { - text: `text marker normal`, + text: 'text marker normal', positionOptions: { position: Position.center, }, @@ -560,13 +572,14 @@ function useViewModel() { saveFormat: saveFormat, }); } - setUri( + const resUri = saveFormat === ImageFormat.base64 ? path : Platform.OS === 'android' ? 'file:' + path - : path - ); + : path; + setUri(resUri); + console.log(resUri); setLoading(false); setShow(true); const stat = await RNBlobUtil.fs.stat(path); @@ -698,13 +711,14 @@ function useViewModel() { saveFormat: saveFormat, }); } - setUri( + const resUri = saveFormat === ImageFormat.base64 ? path : Platform.OS === 'android' ? 'file:' + path - : path - ); + : path; + setUri(resUri); + console.log(resUri); setShow(true); setLoading(false); const stat = await RNBlobUtil.fs.stat(path); diff --git a/ios/RCTImageMarker/TextOptions.swift b/ios/RCTImageMarker/TextOptions.swift index 2e4fc81..62df68f 100644 --- a/ios/RCTImageMarker/TextOptions.swift +++ b/ios/RCTImageMarker/TextOptions.swift @@ -21,7 +21,7 @@ class TextOptions: NSObject { throw NSError(domain: ErrorDomainEnum.PARAMS_REQUIRED.rawValue, code: 0, userInfo: [NSLocalizedDescriptionKey: "text is required"]) } - if let positionOpts = opts["positionOptions"] as? [AnyHashable: Any] { + if let positionOpts = opts["position"] as? [AnyHashable: Any] { self.X = Utils.handleDynamicToString(v: positionOpts["X"]) self.Y = Utils.handleDynamicToString(v: positionOpts["Y"]) self.position = positionOpts["position"] != nil ? RCTConvert.MarkerPosition(positionOpts["position"]) : .none diff --git a/ios/RCTImageMarker/TextStyle.swift b/ios/RCTImageMarker/TextStyle.swift index 269b0ee..0b7d6a2 100644 --- a/ios/RCTImageMarker/TextStyle.swift +++ b/ios/RCTImageMarker/TextStyle.swift @@ -30,8 +30,7 @@ class TextStyle: NSObject { self.shadow = nil } self.textBackground = try TextBackground(textBackgroundStyle: (opts["textBackgroundStyle"] as? [AnyHashable : Any])) - let scale = UIScreen.main.scale - let fontSize = opts["fontSize"] != nil ? (RCTConvert.cgFloat(opts["fontSize"]) * scale) : (14.0 * scale) + let fontSize = opts["fontSize"] != nil ? RCTConvert.cgFloat(opts["fontSize"]) : 14.0 self.font = UIFont(name: opts["fontName"] as? String ?? "", size: fontSize) if self.font == nil { self.font = UIFont.systemFont(ofSize: fontSize) diff --git a/package.json b/package.json index 76ac214..7ed4127 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-image-marker", - "version": "1.2.3", + "version": "1.2.4", "description": "Add text or icon watermark to your images", "main": "lib/commonjs/index", "module": "lib/module/index", diff --git a/src/index.ts b/src/index.ts index 7d0cbc3..d6debf4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -376,7 +376,7 @@ export interface TextBackgroundStyle extends Padding { * @example * type: TextBackgroundType.stretchX **/ - type: TextBackgroundType | null; + type?: TextBackgroundType | null; /** * @description background color * @example @@ -452,6 +452,7 @@ export interface TextOptions { **/ text: string; /** + * @deprecated since 1.2.4 use position instead * @description text position options * @example * positionOptions: { @@ -462,6 +463,19 @@ export interface TextOptions { * } */ positionOptions?: PositionOptions; + + /** + * @description text position options + * @example + * positionOptions: { + * X: 10, + * Y: 10, + * // or + * // position: Position.center + * } + */ + position?: PositionOptions; + /** * @description text style * @example @@ -921,6 +935,11 @@ class Marker { }; } + options.watermarkTexts.forEach((item) => { + item.position = item.position || item.positionOptions; + delete item.positionOptions; + }); + options.backgroundImage.src = srcObj; // let mShadowStyle = shadowStyle || {}; // let mTextBackgroundStyle = textBackgroundStyle || {};