wenweiwei 3 years ago
parent
commit
8f9e6805ec

+ 373 - 0
BFCommonKit/Classes/BFCategorys/BFUIImage+Ext.swift

@@ -0,0 +1,373 @@
+//
+//  UIImage+Ext.swift
+//  BFUIKit
+//
+//  Created by SanW on 2020/6/19.
+//  Copyright © 2020 BytesFlow. All rights reserved.
+//
+
+import Foundation
+import BFCommonKit
+
+/// 滑动方向
+public  enum  moveDirection {
+    case moveDirectionNormal
+    case moveDirectionUp
+    case moveDirectionDown
+    case moveDirectionRight
+    case moveDirectionLeft
+}
+
+public extension UIImage {
+    // 从BFframwork bundle 中取图片
+    static func mc_loadImage(_ imageName: String, from bundleName: String, in podName: String) -> UIImage? {
+            
+            var associateBundleURL = Bundle.main.url(forResource: "Frameworks", withExtension: nil)
+            associateBundleURL = associateBundleURL?.appendingPathComponent(podName)
+            associateBundleURL = associateBundleURL?.appendingPathExtension("framework")
+            
+            
+            if associateBundleURL == nil {
+                print("获取bundle失败")
+                return nil
+            }
+            
+            let associateBunle = Bundle.init(url: associateBundleURL!)
+            associateBundleURL = associateBunle?.url(forResource: bundleName, withExtension: "bundle")
+            
+            if associateBundleURL != nil {
+                let bundle = Bundle.init(url: associateBundleURL!)
+                let scale = Int(UIScreen.main.scale)
+                
+                // 适配2x还是3x图片
+                let name = imageName + "@" + String(scale) + "x"
+                let path = bundle?.path(forResource: name, ofType: "png")
+                
+                if path == nil {
+                    print("获取bundle失败")
+                    return nil
+                }
+                let image1 = UIImage.init(contentsOfFile: path!)
+                return image1
+
+            } else {
+                return nil
+            }
+        }
+    
+    
+    func BF_Image(named: String) -> UIImage {
+        let image: UIImage = UIImage(named: named, in: Bundle().BF_mainbundle(), compatibleWith: nil) ?? UIImage()
+        return image
+    }
+
+    class func moduleImage(named: String, moduleName: String,isAssets:Bool = true) -> UIImage? {
+        let image: UIImage? = UIImage(named: named, in: Bundle.current(moduleName: moduleName,isAssets: isAssets), compatibleWith: nil)
+        return image
+    }
+
+    func cropImage(ratio: CGFloat) -> UIImage {
+        // 计算最终尺寸
+        let newSize: CGSize = CGSize(width: size.width, height: size.width * ratio)
+        // 图片绘制区域
+        var rect = CGRect.zero
+        rect.size.width = size.width
+        rect.size.height = size.height
+        rect.origin.x = (newSize.width - size.width) / 2.0
+        rect.origin.y = (newSize.height - size.height) / 2.0
+
+        UIGraphicsBeginImageContext(newSize)
+        draw(in: rect)
+        let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
+        UIGraphicsEndImageContext()
+
+        return scaledImage!
+    }
+
+    func cropImage(newSize: CGSize) -> UIImage {
+        //// 图片绘制区域
+        var rect = CGRect.zero
+        rect.size.width = newSize.width
+        rect.size.height = newSize.width * (size.height / size.width)
+        // 绘制并获取最终图片
+        UIGraphicsBeginImageContext(newSize)
+        draw(in: rect)
+        let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
+        UIGraphicsEndImageContext()
+
+        return scaledImage!
+    }
+
+    func imageWithImage(scaledToSize newSize: CGSize) -> UIImage {
+        UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
+        draw(in: CGRect(origin: CGPoint.zero, size: newSize))
+        let newImage = UIGraphicsGetImageFromCurrentImageContext() ?? self
+        UIGraphicsEndImageContext()
+        return newImage
+    }
+
+    /// 旋转角度
+    /// - Parameter image: <#image description#>
+    /// - Returns: <#description#>
+    func rotateImage(rotate: Int, originWidth: CGFloat, originHeight: CGFloat) -> UIImage {
+        let rotate: CGFloat = CGFloat(3 * Double.pi / 2)
+        let rect = CGRect(x: 0, y: 0, width: originWidth, height: originHeight)
+        let translateX: CGFloat = -rect.size.height
+        let translateY: CGFloat = 0
+        let scaleY = rect.size.width / rect.size.height
+        let scaleX = rect.size.height / rect.size.width
+        UIGraphicsBeginImageContext(rect.size)
+        let context = UIGraphicsGetCurrentContext()
+        //        context!.translateBy(x: 0.0, y: rect.size.height)
+        //        context!.scaleBy(x: 1.0, y: -1.0)
+        context!.rotate(by: rotate)
+        context!.translateBy(x: translateX, y: translateY)
+        context!.scaleBy(x: scaleX, y: scaleY)
+        draw(in: CGRect(x: 0, y: 0, width: rect.size.width, height: rect.size.height))
+        return UIGraphicsGetImageFromCurrentImageContext()!
+    }
+
+    /// 生成三角图
+    /// - Parameters:
+    ///   - size: <#size description#>
+    ///   - tintColor: <#tintColor description#>
+    ///   - convert:是否倒置
+    /// - Returns: <#description#>
+    class func triangleImage(size: CGSize, tintColor: UIColor, direction: moveDirection = .moveDirectionDown) -> UIImage {
+        var startPoint: CGPoint = CGPoint.zero
+        var middlePoint: CGPoint = CGPoint.zero
+        var endPoint: CGPoint = CGPoint.zero
+        switch direction {
+        case .moveDirectionLeft:
+            startPoint = CGPoint(x: size.width, y: 0)
+            middlePoint = CGPoint(x: 0, y: size.height / 2.0)
+            endPoint = CGPoint(x: size.width, y: size.height)
+        case .moveDirectionRight:
+            startPoint = CGPoint(x: 0, y: 0)
+            middlePoint = CGPoint(x: size.width, y: size.height / 2.0)
+            endPoint = CGPoint(x: 0, y: size.height)
+        case .moveDirectionUp:
+            startPoint = CGPoint(x: 0, y: size.height)
+            middlePoint = CGPoint(x: size.width / 2.0, y: 0)
+            endPoint = CGPoint(x: size.width, y: size.height)
+        default:
+            startPoint = CGPoint(x: 0, y: 0)
+            middlePoint = CGPoint(x: size.width / 2.0, y: size.height)
+            endPoint = CGPoint(x: size.width, y: 0)
+        }
+        UIGraphicsBeginImageContextWithOptions(size, false, 0)
+        let ctx = UIGraphicsGetCurrentContext()
+        let path = UIBezierPath()
+        path.move(to: startPoint)
+        path.addLine(to: middlePoint)
+        path.addLine(to: endPoint)
+        path.close()
+        ctx?.setFillColor(tintColor.cgColor)
+        path.fill()
+        let image = UIGraphicsGetImageFromCurrentImageContext()!
+        UIGraphicsEndImageContext()
+        return image
+    }
+    
+    func nx_scaleWithMaxLength(maxLength: CGFloat,completion: @escaping ( _ image: UIImage) -> Void)  {
+        
+        var maxWidth: CGFloat = maxLength
+        var maxHeight: CGFloat = maxLength
+
+        if size.width != size.height {
+            if size.width > size.height {
+                // 按照宽 来缩放
+                let imageScale: CGFloat = maxLength / size.width
+
+                maxHeight = size.height * imageScale
+            } else if size.width < size.height {
+                let imageScale: CGFloat = maxLength / size.height
+
+                maxWidth = size.width * imageScale
+            }
+        }
+       self.processImage(image: self, size:  CGSize(width: maxWidth, height: maxHeight)) { newImage in
+            completion(newImage)
+       }
+    }
+
+    /// 按照最短边缩放  add by ak
+    /// - Parameter maxLength: 边长最大值
+    func nx_scaleWithMaxLength(maxLength: CGFloat) -> UIImage {
+        if size.width > maxLength || size.height > maxLength {
+            var maxWidth: CGFloat = maxLength
+            var maxHeight: CGFloat = maxLength
+
+            if size.width != size.height {
+                if size.width > size.height {
+                    // 按照宽 来缩放
+                    let imageScale: CGFloat = maxLength / size.width
+
+                    maxHeight = size.height * imageScale
+                } else if size.width < size.height {
+                    let imageScale: CGFloat = maxLength / size.height
+
+                    maxWidth = size.width * imageScale
+                }
+            }
+
+            // 返回新的改变大小后的图片
+            return nx_scaleToSize(size: CGSize(width: maxWidth, height: maxHeight))
+        }
+
+        return self
+    }
+    
+    func processImage(image: UIImage, size: CGSize,completion: @escaping ( _ image: UIImage) -> Void) {
+        DispatchQueue.global().async {
+            var width: CGFloat = CGFloat(image.cgImage?.width ?? 0)
+            var height: CGFloat = CGFloat(image.cgImage?.height ?? 0)
+
+            let verticalRadio: CGFloat = size.height * 1.0 / height
+            let horizontalRadio: CGFloat = size.width * 1.0 / width
+
+            var radio: CGFloat = 1
+            if verticalRadio > 1, horizontalRadio > 1 {
+                radio = verticalRadio > horizontalRadio ? horizontalRadio : verticalRadio
+            } else {
+                radio = verticalRadio < horizontalRadio ? verticalRadio : horizontalRadio
+            }
+
+            width = width * radio
+            height = height * radio
+
+            let xPos: CGFloat = (size.width - width) / 2
+            let yPos: CGFloat = (size.height - height) / 2
+
+            // 创建一个bitmap的context
+            // 并把它设置成为当前正在使用的context
+            UIGraphicsBeginImageContext(size)
+
+            // 绘制改变大小的图片
+            var rect = CGRect.zero
+            rect.size.width = width
+            rect.size.height = height
+            rect.origin.x = xPos
+            rect.origin.y = yPos
+
+            image.draw(in: rect)
+
+            // 从当前context中创建一个改变大小后的图片
+            let scaledImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
+            
+            // 使当前的context出堆栈
+            UIGraphicsEndImageContext()
+            completion(scaledImage)
+        }
+     
+    }
+
+    /// 缩放到指定大小 add by ak
+    /// - Parameter size: 新的大小
+    func nx_scaleToSize(size: CGSize) -> UIImage {
+        var width: CGFloat = CGFloat(cgImage!.width)
+        var height: CGFloat = CGFloat(cgImage!.height)
+
+        let verticalRadio: CGFloat = size.height * 1.0 / height
+        let horizontalRadio: CGFloat = size.width * 1.0 / width
+
+        var radio: CGFloat = 1
+        if verticalRadio > 1, horizontalRadio > 1 {
+            radio = verticalRadio > horizontalRadio ? horizontalRadio : verticalRadio
+        } else {
+            radio = verticalRadio < horizontalRadio ? verticalRadio : horizontalRadio
+        }
+
+        width = width * radio
+        height = height * radio
+
+        let xPos: CGFloat = (size.width - width) / 2
+        let yPos: CGFloat = (size.height - height) / 2
+
+        // 创建一个bitmap的context
+        // 并把它设置成为当前正在使用的context
+        UIGraphicsBeginImageContext(size)
+
+        // 绘制改变大小的图片
+        var rect = CGRect.zero
+        rect.size.width = width
+        rect.size.height = height
+        rect.origin.x = xPos
+        rect.origin.y = yPos
+
+        draw(in: rect)
+
+        // 从当前context中创建一个改变大小后的图片
+        let scaledImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
+        
+        // 使当前的context出堆栈
+        UIGraphicsEndImageContext()
+        
+        // 返回新的改变大小后的图片
+        return scaledImage
+    }
+
+    // 将图片裁剪成指定比例(多余部分自动删除)let image3 = image.crop(ratio: 1) /将图片转成 1:1 比例(正方形)
+    func nxcrop(ratio: CGFloat) -> UIImage {
+        // 计算最终尺寸
+        var newSize: CGSize!
+        if size.width / size.height > ratio {
+            newSize = CGSize(width: size.height * ratio, height: size.height)
+        } else {
+            newSize = CGSize(width: size.width, height: size.width / ratio)
+        }
+
+        ////图片绘制区域
+        var rect = CGRect.zero
+        rect.size.width = size.width
+        rect.size.height = size.height
+        rect.origin.x = (newSize.width - size.width) / 2.0
+        rect.origin.y = (newSize.height - size.height) / 2.0
+
+        // 绘制并获取最终图片
+        UIGraphicsBeginImageContext(newSize)
+        draw(in: rect)
+        let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
+        UIGraphicsEndImageContext()
+
+        return scaledImage!
+    }
+
+    /// 改变图片主题颜色
+    /// - Parameters:
+    ///   - color: <#color description#>
+    ///   - blendMode: <#blendMode description#>
+    /// - Returns: <#description#>
+    func tintImage(color: UIColor, blendMode: CGBlendMode) -> UIImage? {
+        let rect = CGRect(origin: CGPoint.zero, size: size)
+        UIGraphicsBeginImageContextWithOptions(size, false, scale)
+        color.setFill()
+        UIRectFill(rect)
+        draw(in: rect, blendMode: blendMode, alpha: 1.0)
+        let tintedImage = UIGraphicsGetImageFromCurrentImageContext()
+        UIGraphicsEndImageContext()
+        return tintedImage
+    }
+    
+    /// 保存图片文件到指定目录, 如果目录已经存在会先删除老文件
+    /// - Parameters:
+    ///   - currentImage: 图片数据
+    ///   - persent: 质量
+    ///   - outFilePath: 输出目录
+    class func saveImage(currentImage: UIImage,outFilePath: String) {
+        // 文件存在先删除老文件
+        if FileManager.default.fileExists(atPath: outFilePath) {
+            do {
+                try FileManager.default.removeItem(at: NSURL.fileURL(withPath: outFilePath))
+            } catch {
+                BFLog(message: "删除文件出错 == \(error) \(outFilePath)")
+            }
+        }
+        
+        if let imageData = currentImage.pngData() {
+            try? imageData.write(to: URL(fileURLWithPath: outFilePath))
+            print("保存图片成功到:filePath=\(outFilePath)")
+        }
+    }
+
+}

+ 201 - 0
BFCommonKit/Classes/BFCategorys/UIImage+NXCategory.h

@@ -0,0 +1,201 @@
+//
+//  UIImage+UIImage_NXCategory.h
+//  AKImovie
+//
+//  Created by AK on 16/2/21.
+//  Copyright © 2016年 ak. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef NS_ENUM(NSInteger, NXCropImageStyle) {
+    NXCropImageStyleRight = 0,               // 右半部分
+    NXCropImageStyleCenter = 1,              // 中间部分
+    NXCropImageStyleLeft = 2,                // 左半部分
+    NXCropImageStyleRightOneOfThird = 3,     // 右侧三分之一部分
+    NXCropImageStyleCenterOneOfThird = 4,    // 中间三分之一部分
+    NXCropImageStyleLeftOneOfThird = 5,      // 左侧三分之一部分
+    NXCropImageStyleRightQuarter = 6,        // 右侧四分之一部分
+    NXCropImageStyleCenterRightQuarter = 7,  // 中间右侧四分之一部分
+    NXCropImageStyleCenterLeftQuarter = 8,   // 中间左侧四分之一部分
+    NXCropImageStyleLeftQuarter = 9,         // 左侧四分之一部分
+};
+
+@interface UIImage (NXCategory)
+
+#pragma mark - blur 效果
+/**
+ 给图片打马赛克
+ @param image 原始图片
+ @param blur 值越 blurry 就越大
+ @return 处理后的图片
+ */
++ (UIImage *)nx_blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur;
+
+/**
+  boxblur image 这个要在整理
+
+  @param toBlurImage 要处理的图片
+  @return 处理后图片
+ */
++ (UIImage *)nx_boxblurImage:(UIImage *)toBlurImage;
+
+#pragma mark - 旋转
+/**
+  照片旋转90度,如从系统相册中取出的原图要转正
+
+ @param aImage 原图
+ @param isFront YES 为前置拍照
+ @return 转正后图片
+ */
++ (UIImage *)nx_fixOrientation:(UIImage *)aImage isFront:(BOOL)isFront;
+
+/**
+ 旋转图片
+
+ @param image 原图
+ @param orientation 旋转的方向
+ @return 旋转后的图片
+ */
++ (UIImage *)nx_rotationImage:(UIImage *)image orientation:(UIImageOrientation)orientation;
+
+#pragma mark - 缩放
+/**
+ 等比缩放图片
+
+ @param size 放到的大小(单位为像素)
+ @return 处理后的图片
+ */
+- (UIImage *)nx_scaleToSize:(CGSize)size;
+
+/**
+ 等比缩放图片 按照最短边缩放
+ @param maxLength 边长最大值 (单位为像素)
+ @return 处理后的图片
+ */
+- (UIImage *)nx_scaleWithMaxLength:(float)maxLength;
+
+#pragma mark - 截取
+/**
+ 截取 uiimage 指定区域
+
+ @param style 类型为 NXCropImageStyle
+ @return 裁剪后的图片
+ */
+- (UIImage *)nx_imageByCroppingWithStyle:(NXCropImageStyle)style;
+
+/**
+  截取 uiimage 指定区域
+
+ @param rect 裁剪区域
+ @return 裁剪后的图片
+ */
+- (UIImage *)imageByCroppingWithRect:(CGRect)rect;
+
+
+/**
+ 将图片按照最短边等比截取图片中间部分
+
+ @return 截取后到正方形图片
+ */
+- (UIImage *)nx_cropImageToSquare;
+
+/**
+ *  将图片等比绘制到正方形画布中并重新生成新图
+ *
+ *  @return 处理后的图片
+ */
+- (UIImage *)nx_zoomImageToSquare;
+
+/**
+ 将图片等比缩放的指定的画布中并生成新图。(跟画布比例不一样的做 左右或者上下留白处理)
+
+ @param size 指定画布大小
+ @return 处理后的新图
+ */
+- (UIImage *)nx_zoomWithSize:(CGSize)size;
+
+/**
+ 高清截屏 opaque 为no 有透明度速度会慢一些
+
+ @param view 指定的VIEW
+ @return 截屏图片
+ */
++ (UIImage *)nx_screenHierarchyShots:(UIView *)view;
+
+/**
+ 高清截屏
+
+ @param view 指定的VIEW
+ @param opaque 透明开关,如果图形完全不用透明,设置为YES以优化位图的存储。
+ @return 截屏图片
+ */
++ (UIImage *)nx_screenHierarchyShots:(UIView *)view isOpaque:(BOOL)opaque;
+
+/**
+ 获得裁剪图片
+
+ e.g.
+ int squalWidth = MIN(self.clipImage.size.width, self.clipImage.size.height);
+
+ float clipX = _clipScroll.contentOffset.x;
+ float clipY = _clipScroll.contentOffset.y;
+ CGRect rect = CGRectMake(clipX, clipY, NX_MAIN_SCREEN_WIDTH, NX_MAIN_SCREEN_WIDTH);
+
+ clipedImage =
+ [UIImage nx_cropImageView:_bigImageView toRect:rect zoomScale:1
+ containerView:_backView outputWith:squalWidth];
+
+ @param imageView 原始VIEW
+ @param rect 截取区域
+ @param zoomScale 缩放大小
+ @param containerView 显示区域VIEW
+ @param outputWith 输出大小
+ @return 处理后图片
+ */
++ (UIImage *)nx_cropImageView:(UIImageView *)imageView
+                       toRect:(CGRect)rect
+                    zoomScale:(double)zoomScale
+                containerView:(UIView *)containerView
+                   outputWith:(CGFloat)outputWith;
+
+#pragma mark - 圆角
+/**
+ 切圆角 可防止离屏渲染
+ e.g.
+ UIImage *placeHolder = [[UIImage imageNamed:@"userIcon"] circleImage];
+
+ @param img 原图片
+ @return 处理后的图片
+ */
++ (UIImage *)nx_circleImage:(UIImage *)img;
+
+/** 切圆角 可防止离屏渲染
+ * @param image 需要进行圆角的图片
+ * @param direction 切割的方向
+ * @param cornerRadii 圆角半径
+ * @param borderWidth 边框宽度
+ * @param borderColor 边框颜色
+ * @param backgroundColor 背景色
+ * @return 处理后的图片
+ */
++ (UIImage *)nx_circleImage:(UIImage *)image cuttingDirection:(UIRectCorner)direction cornerRadii:(CGFloat)cornerRadii borderWidth:(CGFloat)borderWidth borderColor:(UIColor *)borderColor backgroundColor:(UIColor *)backgroundColor;
+
+/**
+ 获取当前屏幕大小的的开屏页图片
+ 
+ @return 开屏页图片
+ */
++ (UIImage *)nx_launchImage;
+
+
+/**
+ 把指定颜色背景变成透明
+
+ @param image 原图数据
+ @param color 原背景色
+ @return 背景透明后的图
+ */
++ (UIImage*)transparentBackClear:(UIImage*)image color:(UIColor*)color;
+
+@end

+ 642 - 0
BFCommonKit/Classes/BFCategorys/UIImage+NXCategory.m

@@ -0,0 +1,642 @@
+//
+//  UIImage+UIImage_NXCategory.m
+//  AKImovie
+//
+//  Created by AK on 16/2/21.
+//  Copyright © 2016年 ak. All rights reserved.
+//
+
+#import "UIImage+NXCategory.h"
+#import <Accelerate/Accelerate.h>
+
+@implementation UIImage (NXCategory)
+
+#pragma mark - blur 效果
++ (UIImage *)nx_blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur
+{
+    CIImage *inputImage = [CIImage imageWithCGImage:image.CGImage];
+    CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"
+                                  keysAndValues:kCIInputImageKey, inputImage, @"inputRadius", @(blur), nil];
+
+    CIImage *outputImage = filter.outputImage;
+    CIContext *context = [CIContext contextWithOptions:nil];
+    CGImageRef outImage = [context createCGImage:outputImage fromRect:[outputImage extent]];
+    return [UIImage imageWithCGImage:outImage];
+}
+
++ (UIImage *)nx_boxblurImage:(UIImage *)toBlurImage
+{
+    UIImage *newImage =
+
+        [toBlurImage nx_scaleToSize:CGSizeMake(toBlurImage.size.width / 2., toBlurImage.size.height / 2.)];
+
+    NSData *jpgData = UIImageJPEGRepresentation(newImage, 0.01);
+
+    UIImage *image = [UIImage imageWithData:jpgData];
+    CGFloat blur = 0.3f;
+
+    int boxSize = (int)(blur * 40);
+    boxSize = boxSize - (boxSize % 2) + 1;
+
+    CGImageRef img = image.CGImage;
+    vImage_Buffer inBuffer, outBuffer;
+    vImage_Error error;
+    void *pixelBuffer;
+
+    // create vImage_Buffer with data from CGImageRef
+    CGDataProviderRef inProvider = CGImageGetDataProvider(img);
+    CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);
+
+    inBuffer.width = CGImageGetWidth(img);
+    inBuffer.height = CGImageGetHeight(img);
+    inBuffer.rowBytes = CGImageGetBytesPerRow(img);
+
+    inBuffer.data = (void *)CFDataGetBytePtr(inBitmapData);
+
+    // create vImage_Buffer for output
+    pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));
+
+    if (pixelBuffer == NULL) NSLog(@"No pixelbuffer");
+
+    outBuffer.data = pixelBuffer;
+    outBuffer.width = CGImageGetWidth(img);
+    outBuffer.height = CGImageGetHeight(img);
+    outBuffer.rowBytes = CGImageGetBytesPerRow(img);
+
+    // perform convolution
+    error =
+        vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend)
+            ?: vImageBoxConvolve_ARGB8888(&outBuffer, &inBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend)
+                   ?: vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL,
+                                                 kvImageEdgeExtend);
+
+    if (error)
+    {
+        NSLog(@"error from convolution %ld", error);
+    }
+
+    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+    CGContextRef ctx = CGBitmapContextCreate(outBuffer.data, outBuffer.width, outBuffer.height, 8, outBuffer.rowBytes,
+                                             colorSpace, (CGBitmapInfo)kCGImageAlphaNoneSkipLast);
+    CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
+    UIImage *returnImage = [UIImage imageWithCGImage:imageRef];
+
+    // clean up
+    CGContextRelease(ctx);
+    CGColorSpaceRelease(colorSpace);
+
+    free(pixelBuffer);
+    CFRelease(inBitmapData);
+    CGImageRelease(imageRef);
+
+    return returnImage;
+}
+
+#pragma mark - 旋转
++ (UIImage *)nx_fixOrientation:(UIImage *)aImage isFront:(BOOL)isFront;
+{
+    // No-op if the orientation is already correct
+    if (aImage.imageOrientation == UIImageOrientationUp) return aImage;
+
+    // We need to calculate the proper transformation to make the image upright.
+    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
+    CGAffineTransform transform = CGAffineTransformIdentity;
+
+    if (isFront)
+    {
+        transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
+        transform = CGAffineTransformScale(transform, -1, 1);
+    }
+
+    switch (aImage.imageOrientation)
+    {
+        case UIImageOrientationDown:
+        case UIImageOrientationDownMirrored:
+            transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
+            transform = CGAffineTransformRotate(transform, M_PI);
+            break;
+
+        case UIImageOrientationLeft:
+        case UIImageOrientationLeftMirrored:
+            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
+            transform = CGAffineTransformRotate(transform, M_PI_2);
+            break;
+
+        case UIImageOrientationRight:
+        case UIImageOrientationRightMirrored:
+            transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
+            transform = CGAffineTransformRotate(transform, -M_PI_2);
+            break;
+        default:
+            break;
+    }
+
+    switch (aImage.imageOrientation)
+    {
+        case UIImageOrientationUpMirrored:
+        case UIImageOrientationDownMirrored:
+            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
+            transform = CGAffineTransformScale(transform, -1, 1);
+            break;
+
+        case UIImageOrientationLeftMirrored:
+        case UIImageOrientationRightMirrored:
+            transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
+            transform = CGAffineTransformScale(transform, -1, 1);
+            break;
+        default:
+            break;
+    }
+
+    // Now we draw the underlying CGImage into a new context, applying the
+    // transform
+    // calculated above.
+    CGContextRef ctx =
+        CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height, CGImageGetBitsPerComponent(aImage.CGImage),
+                              0, CGImageGetColorSpace(aImage.CGImage), CGImageGetBitmapInfo(aImage.CGImage));
+    CGContextConcatCTM(ctx, transform);
+    switch (aImage.imageOrientation)
+    {
+        case UIImageOrientationLeft:
+        case UIImageOrientationLeftMirrored:
+        case UIImageOrientationRight:
+        case UIImageOrientationRightMirrored:
+            // Grr...
+            CGContextDrawImage(ctx, CGRectMake(0, 0, aImage.size.height, aImage.size.width), aImage.CGImage);
+            break;
+
+        default:
+            CGContextDrawImage(ctx, CGRectMake(0, 0, aImage.size.width, aImage.size.height), aImage.CGImage);
+            break;
+    }
+
+    // And now we just create a new UIImage from the drawing context
+    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
+    UIImage *img = [UIImage imageWithCGImage:cgimg];
+    CGContextRelease(ctx);
+    CGImageRelease(cgimg);
+    return img;
+}
+
+// 旋转
++ (UIImage *)nx_rotationImage:(UIImage *)image orientation:(UIImageOrientation)orientation
+{
+    long double rotate = 0.0;
+    CGRect rect;
+    float translateX = 0;
+    float translateY = 0;
+    float scaleX = 1.0;
+    float scaleY = 1.0;
+
+    switch (orientation)
+    {
+        case UIImageOrientationLeft:
+            rotate = M_PI_2;
+            rect = CGRectMake(0, 0, image.size.height, image.size.width);
+            translateX = 0;
+            translateY = -rect.size.width;
+            scaleY = rect.size.width / rect.size.height;
+            scaleX = rect.size.height / rect.size.width;
+            break;
+        case UIImageOrientationRight:
+            rotate = 3 * M_PI_2;
+            rect = CGRectMake(0, 0, image.size.height, image.size.width);
+            translateX = -rect.size.height;
+            translateY = 0;
+            scaleY = rect.size.width / rect.size.height;
+            scaleX = rect.size.height / rect.size.width;
+            break;
+        case UIImageOrientationDown:
+            rotate = M_PI;
+            rect = CGRectMake(0, 0, image.size.width, image.size.height);
+            translateX = -rect.size.width;
+            translateY = -rect.size.height;
+            break;
+        default:
+            rotate = 0.0;
+            rect = CGRectMake(0, 0, image.size.width, image.size.height);
+            translateX = 0;
+            translateY = 0;
+            break;
+    }
+
+    UIGraphicsBeginImageContext(rect.size);
+    CGContextRef context = UIGraphicsGetCurrentContext();
+    //做CTM变换
+    CGContextTranslateCTM(context, 0.0, rect.size.height);
+    CGContextScaleCTM(context, 1.0, -1.0);
+    CGContextRotateCTM(context, rotate);
+    CGContextTranslateCTM(context, translateX, translateY);
+
+    CGContextScaleCTM(context, scaleX, scaleY);
+    //绘制图片
+    CGContextDrawImage(context, CGRectMake(0, 0, rect.size.width, rect.size.height), image.CGImage);
+
+    UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();
+    NSLog(@"image size %f---%f", image.size.width, image.size.height);
+    UIGraphicsEndImageContext();
+    return newPic;
+}
+
+#pragma mark - 缩放
+- (UIImage *)nx_scaleToSize:(CGSize)size
+{
+    CGFloat width = CGImageGetWidth(self.CGImage);
+    CGFloat height = CGImageGetHeight(self.CGImage);
+
+    float verticalRadio = size.height * 1.0 / height;
+    float horizontalRadio = size.width * 1.0 / width;
+
+    float radio = 1;
+    if (verticalRadio > 1 && horizontalRadio > 1)
+    {
+        radio = verticalRadio > horizontalRadio ? horizontalRadio : verticalRadio;
+    }
+    else
+    {
+        radio = verticalRadio < horizontalRadio ? verticalRadio : horizontalRadio;
+    }
+
+    width = width * radio;
+    height = height * radio;
+
+    int xPos = (size.width - width) / 2;
+    int yPos = (size.height - height) / 2;
+
+    // 创建一个bitmap的context
+    // 并把它设置成为当前正在使用的context
+    UIGraphicsBeginImageContext(size);
+
+    // 绘制改变大小的图片
+    [self drawInRect:CGRectMake(xPos, yPos, width, height)];
+
+    // 从当前context中创建一个改变大小后的图片
+    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
+
+    // 使当前的context出堆栈
+    UIGraphicsEndImageContext();
+
+    // 返回新的改变大小后的图片
+    return scaledImage;
+}
+
+//按照最短边缩放 maxlength 边长最大值
+- (UIImage *)nx_scaleWithMaxLength:(float)maxLength
+{
+    if (self.size.width > maxLength || self.size.height > maxLength)
+    {
+        float maxWidth = maxLength;
+        float maxHeight = maxLength;
+
+        if (self.size.width != self.size.height)
+        {
+            if (self.size.width > self.size.height)
+            {
+                //按照宽 来缩放
+                float imageScale = maxLength / self.size.width;
+                maxHeight = self.size.height * imageScale;
+            }
+            else if (self.size.width < self.size.height)
+            {
+                float imageScale = maxLength / self.size.height;
+
+                maxWidth = self.size.width * imageScale;
+            }
+        }
+        // 返回新的改变大小后的图片
+        return [self nx_scaleToSize:CGSizeMake(maxWidth, maxHeight)];
+    }
+
+    return self;
+}
+
+#pragma mark - 截取
+- (UIImage *)nx_imageByCroppingWithStyle:(NXCropImageStyle)style
+{
+    CGRect rect = CGRectZero;
+    switch (style)
+    {
+        case NXCropImageStyleLeft:
+            rect = CGRectMake(0, 0, self.size.width / 2, self.size.height);
+            break;
+        case NXCropImageStyleCenter:
+            rect = CGRectMake(self.size.width / 4, 0, self.size.width / 2, self.size.height);
+            break;
+        case NXCropImageStyleRight:
+            rect = CGRectMake(self.size.width / 2, 0, self.size.width / 2, self.size.height);
+            break;
+        case NXCropImageStyleLeftOneOfThird:
+            rect = CGRectMake(0, 0, self.size.width / 3, self.size.height);
+            break;
+        case NXCropImageStyleCenterOneOfThird:
+            rect = CGRectMake(self.size.width / 3, 0, self.size.width / 3, self.size.height);
+            break;
+        case NXCropImageStyleRightOneOfThird:
+            rect = CGRectMake(self.size.width / 3 * 2, 0, self.size.width / 3, self.size.height);
+            break;
+        case NXCropImageStyleLeftQuarter:
+            rect = CGRectMake(0, 0, self.size.width / 4, self.size.height);
+            break;
+        case NXCropImageStyleCenterLeftQuarter:
+            rect = CGRectMake(self.size.width / 4, 0, self.size.width / 4, self.size.height);
+            break;
+        case NXCropImageStyleCenterRightQuarter:
+            rect = CGRectMake(self.size.width / 4 * 2, 0, self.size.width / 4, self.size.height);
+            break;
+        case NXCropImageStyleRightQuarter:
+            rect = CGRectMake(self.size.width / 4 * 3, 0, self.size.width / 4, self.size.height);
+            break;
+        default:
+            break;
+    }
+
+    return [self imageByCroppingWithRect:rect];
+}
+
+- (UIImage *)imageByCroppingWithRect:(CGRect)rect
+{
+    CGImageRef imageRef = self.CGImage;
+    CGImageRef imagePartRef = CGImageCreateWithImageInRect(imageRef, rect);
+    UIImage *cropImage = [UIImage imageWithCGImage:imagePartRef];
+    CGImageRelease(imagePartRef);
+    return cropImage;
+}
+
+- (UIImage *)nx_cropImageToSquare{
+
+    if(self.size.width == self.size.height)
+    {
+        return self;
+    }
+    double w = self.size.width;
+    double h = self.size.height;
+    double m = MIN(w, h);
+    CGRect rect = CGRectMake((self.size.width - m)/2.0f , (self.size.height - m)/2.0f, m, m);
+    return [self imageByCroppingWithRect:rect];
+}
+
+- (UIImage *)nx_zoomWithSize:(CGSize)size{
+
+    if(self == nil)
+    {
+        return nil;
+    }
+    
+    double w  = self.size.width;
+    double h =self.size.height;
+    double vRatio = w / size.width;
+    double hRatio = h / size.height;
+    double ratio = MAX(vRatio, hRatio);
+    w /= ratio;
+    h /= ratio;
+    CGRect drawRect = CGRectMake((size.width - w)/2.0f , (size.height - h)/2.0f, w, h);
+    // 创建一个bitmap的context
+    // 并把它设置成为当前正在使用的context
+    UIGraphicsBeginImageContext(size);
+    // 绘制改变大小的图片
+    [self drawInRect:drawRect];
+    // 从当前context中创建一个改变大小后的图片
+    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
+    // 使当前的context出堆栈
+    UIGraphicsEndImageContext();
+    return  scaledImage;
+    
+}
+
+
+- (UIImage *)nx_zoomImageToSquare
+{
+    if (self == nil)
+    {
+        return nil;
+    }
+    double tw = MIN(self.size.width, self.size.height);
+
+    return [self nx_scaleToSize:CGSizeMake(tw, tw)];
+}
+
+//截屏 有透明的
++ (UIImage *)nx_screenHierarchyShots:(UIView *)view { return [UIImage nx_screenHierarchyShots:view isOpaque:NO]; }
+//高清截屏 opaque 是否有透明图层
++ (UIImage *)nx_screenHierarchyShots:(UIView *)view isOpaque:(BOOL)opaque
+{
+    // size——同UIGraphicsBeginImageContext
+    // opaque—透明开关,如果图形完全不用透明,设置为YES以优化位图的存储。
+    // scale—–缩放因子
+    UIGraphicsBeginImageContextWithOptions(view.bounds.size, opaque, 0);
+    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
+    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
+    UIGraphicsEndImageContext();
+    return image;
+}
+
+/// 获得裁剪后的图片
++ (UIImage *)nx_cropImageView:(UIImageView *)imageView
+                       toRect:(CGRect)rect
+                    zoomScale:(double)zoomScale
+                containerView:(UIView *)containerView
+                   outputWith:(CGFloat)outputWith
+{
+    CGAffineTransform transform = CGAffineTransformIdentity;
+    // 平移的处理
+    CGRect imageViewRect = [imageView convertRect:imageView.bounds toView:containerView];
+    CGPoint point = CGPointMake(imageViewRect.origin.x + imageViewRect.size.width / 2,
+                                imageViewRect.origin.y + imageViewRect.size.height / 2);
+
+    CGPoint zeroPoint =
+        CGPointMake(CGRectGetWidth(containerView.frame) / 2., CGRectGetHeight(containerView.frame) / 2.);
+
+    CGPoint translation = CGPointMake(point.x - zeroPoint.x, point.y - zeroPoint.y);
+    transform = CGAffineTransformTranslate(transform, translation.x, translation.y);
+    // 缩放的处理
+    transform = CGAffineTransformScale(transform, zoomScale, zoomScale);
+
+    CGImageRef imageRef = [self nx_newTransformedImage:transform
+                                           sourceImage:imageView.image.CGImage
+                                            sourceSize:imageView.image.size
+                                           outputWidth:outputWith
+                                              cropSize:rect.size
+                                         imageViewSize:imageView.frame.size];
+    UIImage *cropedImage = [UIImage imageWithCGImage:imageRef];
+    CGImageRelease(imageRef);
+    return cropedImage;
+}
+
++ (CGImageRef)nx_newTransformedImage:(CGAffineTransform)transform
+                         sourceImage:(CGImageRef)sourceImage
+                          sourceSize:(CGSize)sourceSize
+                         outputWidth:(CGFloat)outputWidth
+                            cropSize:(CGSize)cropSize
+                       imageViewSize:(CGSize)imageViewSize
+{
+    CGImageRef source = [self nx_newScaledImage:sourceImage toSize:sourceSize];
+
+    CGFloat aspect = cropSize.height / cropSize.width;
+    CGSize outputSize = CGSizeMake(outputWidth, outputWidth * aspect);
+
+    CGContextRef context =
+        CGBitmapContextCreate(NULL, outputSize.width, outputSize.height, CGImageGetBitsPerComponent(source), 0,
+                              CGImageGetColorSpace(source), CGImageGetBitmapInfo(source));
+    CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
+    CGContextFillRect(context, CGRectMake(0, 0, outputSize.width, outputSize.height));
+
+    CGAffineTransform uiCoords =
+        CGAffineTransformMakeScale(outputSize.width / cropSize.width, outputSize.height / cropSize.height);
+    uiCoords = CGAffineTransformTranslate(uiCoords, cropSize.width / 2.0, cropSize.height / 2.0);
+    uiCoords = CGAffineTransformScale(uiCoords, 1.0, -1.0);
+    CGContextConcatCTM(context, uiCoords);
+
+    CGContextConcatCTM(context, transform);
+    CGContextScaleCTM(context, 1.0, -1.0);
+
+    CGContextDrawImage(context, CGRectMake(-imageViewSize.width / 2, -imageViewSize.height / 2.0, imageViewSize.width,
+                                           imageViewSize.height),
+                       source);
+    CGImageRef resultRef = CGBitmapContextCreateImage(context);
+    CGContextRelease(context);
+    CGImageRelease(source);
+    return resultRef;
+}
+
++ (CGImageRef)nx_newScaledImage:(CGImageRef)source toSize:(CGSize)size
+{
+    CGSize srcSize = size;
+    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
+    CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, 0, rgbColorSpace,
+                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
+    CGColorSpaceRelease(rgbColorSpace);
+
+    CGContextSetInterpolationQuality(context, kCGInterpolationNone);
+    CGContextTranslateCTM(context, size.width / 2, size.height / 2);
+
+    CGContextDrawImage(context, CGRectMake(-srcSize.width / 2, -srcSize.height / 2, srcSize.width, srcSize.height),
+                       source);
+
+    CGImageRef resultRef = CGBitmapContextCreateImage(context);
+    CGContextRelease(context);
+    return resultRef;
+}
+
+#pragma mark - 圆角
++ (UIImage *)nx_circleImage:(UIImage *)img
+{
+   return [self nx_circleImage:img cuttingDirection:UIRectCornerAllCorners cornerRadii:img.size.height/2. borderWidth:0 borderColor: [UIColor clearColor] backgroundColor: [UIColor clearColor]];
+}
+
++ (UIImage *)nx_circleImage:(UIImage *)image cuttingDirection:(UIRectCorner)direction cornerRadii:(CGFloat)cornerRadii borderWidth:(CGFloat)borderWidth borderColor:(UIColor *)borderColor backgroundColor:(UIColor *)backgroundColor
+{
+    //处理后的数据
+    UIImage * newImage = nil;
+    if (image.size.height != 0 && image.size.width != 0)
+    {
+        if (cornerRadii == 0)
+        {
+            cornerRadii = image.size.height / 2;
+        }
+        CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
+        UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale);
+        CGContextRef currnetContext = UIGraphicsGetCurrentContext();
+        if (currnetContext) {
+            
+            UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:direction cornerRadii:CGSizeMake(cornerRadii - borderWidth, cornerRadii - borderWidth)];
+            CGContextAddPath(currnetContext,path.CGPath);
+            CGContextClip(currnetContext);
+            
+            [image drawInRect:rect];
+            [borderColor setStroke];// 画笔颜色
+            [backgroundColor setFill];// 填充颜色
+            [path stroke];
+            [path fill];
+            newImage = UIGraphicsGetImageFromCurrentImageContext();
+            UIGraphicsEndImageContext();
+        }
+        
+        return newImage;
+    }
+    
+    return newImage;
+}
+
++ (UIImage *)nx_launchImage
+{
+    CGSize viewSize  = [UIScreen mainScreen].bounds.size;
+    
+    NSString * viewOrientation = @"Portrait";
+    NSString * launchImageName = nil;
+    NSArray * imageDict = [[[NSBundle mainBundle] infoDictionary]valueForKey:@"UILaunchImages"];
+    for (NSDictionary  * dict in imageDict)
+    {
+        CGSize imageSize = CGSizeFromString(dict[@"UILaunchImageSize"]);
+        if (CGSizeEqualToSize(imageSize, viewSize) && [viewOrientation isEqualToString:dict[@"UILaunchImageOrientation"]])
+        {
+            launchImageName = dict[@"UILaunchImageName"];
+        }
+    }
+    UIImage * launchImage = [UIImage imageNamed:launchImageName];
+    
+    return launchImage;
+}
+
+
++ (UIImage*)transparentBackClear:(UIImage*)image color:(UIColor*)color
+{
+    // 分配内存
+    const int imageWidth = image.size.width;
+    const int imageHeight = image.size.height;
+    size_t bytesPerRow = imageWidth * 4;
+    uint32_t* rgbImageBuf = (uint32_t*)malloc(bytesPerRow * imageHeight);
+    
+    // 创建context
+    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+    CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace,
+                                                 kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
+    CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage);
+    
+    // 遍历像素
+    int pixelNum = imageWidth * imageHeight;
+    uint32_t* pCurPtr = rgbImageBuf;
+    for (int i = 0; i < pixelNum; i++, pCurPtr++)
+    {
+        if ((*pCurPtr & 0xFFFFFF00) == 0xffffff00) {
+            
+            // 此处把白色背景颜色给变为透明
+            uint8_t* ptr = (uint8_t*)pCurPtr;
+            ptr[0] = 0;
+            
+        }else{
+            
+            // 改成下面的代码,会将图片转成想要的
+            //            uint8_t* ptr = (uint8_t*)pCurPtr;
+            //
+            //            ptr[3] = 0; //0~255
+            //
+            //            ptr[2] = 0;
+            //
+            //            ptr[1] = 0;
+        }
+    }
+    
+    // 将内存转成image
+    CGDataProviderRef dataProvider =CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, ProviderReleaseData);
+    
+    CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight,8, 32, bytesPerRow, colorSpace,
+                                        kCGImageAlphaLast |kCGBitmapByteOrder32Little, dataProvider,
+                                        NULL, true,kCGRenderingIntentDefault);
+    CGDataProviderRelease(dataProvider);
+    
+    UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef];
+    
+    // 释放
+    CGImageRelease(imageRef);
+    CGContextRelease(context);
+    CGColorSpaceRelease(colorSpace);
+    
+    return resultUIImage;
+}
+
+void ProviderReleaseData (void *info, const void *data, size_t size)
+{
+    free((void*)data);
+}
+
+@end

+ 476 - 0
BFCommonKit/Classes/BFUtility/PQRequestURLUtil.swift

@@ -0,0 +1,476 @@
+//
+//  PQRequestURLUtil.swift
+//  PQSpeed
+//
+//  Created by SanW on 2020/9/21.
+//  Copyright © 2020 BytesFlow. All rights reserved.
+//
+
+import UIKit
+
+// 票圈视频主域名-线上环境
+public let onlineLongvideoapi = "https://speed.piaoquantv.com/longvideoapi/"
+// 票圈视频域名(热榜)-线上环境
+public let onlineDistributionApi = "https://speed.piaoquantv.com/distribution/"
+// 通用域名-eg:数据上报-线上环境
+public let onlineCommonapi = "https://common.piaoquantv.com/commonapi/"
+// 视频创作相关域名-线上环境
+public let onlineClipapiApi = "https://clipapi.piaoquantv.com/longvideoapi/"
+// 创作工具搜索素材相关域名-线上环境
+public let onlineMaterialSearchApi = "https://search-material.piaoquantv.com/"
+// 消息相关域名-线上环境
+public let onlineMessageApi = "https://messageapi.piaoquantv.com/"
+// 票圈Api-线上环境
+public let onlinePQTvApi = "https://api.piaoquantv.com/"
+
+
+// 票圈视频主域名-预发布环境
+public let preLongvideoapi = "https://prespeed.piaoquantv.com/longvideoapi/"
+// 票圈视频域名(热榜)-预发布环境
+public let preDistributionApi = "https://prespeed.piaoquantv.com/distribution/"
+// 通用域名-eg:数据上报-预发布环境
+public let preCommonapi = "https://precommon.piaoquantv.com/commonapi/"
+// 创作工具搜索素材相关域名-预发布环境
+public let preMaterialSearchApi = "https://search-material-pre.piaoquantv.com/"
+// 消息相关域名-预发布环境
+public let preMessageApi = "https://messageapipre.piaoquantv.com/"
+// 票圈Api-预发布环境
+public let prePQTvApi = "https://preapi.piaoquantv.com/"
+
+// 票圈视频主域名-测试环境
+public let testLongvideoapi = "https://videotest.yishihui.com/longvideoapi/"
+// 票圈视频域名(热榜)-测试环境
+public let testDistributionApi = "https://videotest.yishihui.com/distribution/"
+// 通用域名-eg:数据上报-测试环境
+public let testCommonapi = "https://videotest.yishihui.com/commonapi/"
+// 创作工具搜索素材相关域名-测试环境
+public let testMaterialSearchApi = "https://search-material.yishihui.com/"
+// 消息相关域名-测试环境
+public let testMessageApi = "https://messageapitest.yishihui.com/"
+// 票圈Api-测试环境
+public let testPQTvApi = "https://testapi.piaoquantv.com/"
+
+// 票圈视频主域名-北京预发布环境
+public let preBJLongvideoapi = "https://videoprebeijing.piaoquantv.com/longvideoapi/"
+// 票圈视频域名(热榜)-北京预发布环境
+public let preBJDistributionApi = "https://videoprebeijing.piaoquantv.com/distribution/"
+// 通用域名-eg:数据上报-北京预发布环境
+public let preBJCommonapi = "https://precommon.piaoquantv.com/commonapi/"
+public let categroyVideoList = "video/distribute/category/videoList/v2"
+public let recommandPageList = "video/recommend/app/recommandPage/list"
+/// 热榜列表
+public let hotBoardListUrl = "video/list"
+/// 白名单展示
+public let datashowAllowUrl = "datashow/allow"
+// 获取登陆背景图
+public let loginBackgroundUrl = "community/login/background"
+/// 登录
+public let login = "login/app"
+/// 新增虚拟账号
+public let generateVirtualUserUrl = "user/virtual/app/generateVirtualUser"
+/// 手机号注册
+public let phoneRegisterUrl = "register/app/check"
+/// 手机号登录
+public let phoneLoginUrl = "login/app/check"
+/// 苹果账号登录
+public let appleLoginUrl = "app/iphone/login"
+/** 退出登录 */
+public let logoutUrl = "logout/app"
+/** 注销账号 */
+public let cancellationAccUrl = "user/info/addMockData"
+/** 更新用户个人信息 */
+public let updateUserinfoUrl = "user/info/update"
+/** 更新用户个人扩展信息 */
+public let updateExtUserinfoUrl = "user/info/saveExtInfo"
+/** 查询用户状态 1有效,2 已删除,3 已屏蔽,4 敏感 */
+public let userStatusUrl = "user/info/getUserStatus"
+/** 更新用户个人信息 */
+public let ossTempTokenUrl = "oss/getOssTempToken"
+// add by ak 取 STS token uri
+public let getStsTokenUrl = "oss/getStsToken"
+/** 谁的关注 */
+public let idolsUrl = "user/idols"
+/** 谁的粉丝 */
+public let fansUrl = "user/fans"
+/** 我的订阅列表 */
+public let mySubscribesUrl = "user/mySubscribes"
+/** 订阅我的列表 */
+public let otherSubscribesUrl = "user/otherSubscribes"
+/** 个人主页头部信息 */
+public let homepageHeadUrl = "user/info/homepageHead"
+/** 获取用户扩展信息 */
+public let userInfoExtUrl = "user/info/getUserInfoExt"
+/** 某人的收藏夹集合 */
+public let userVideoFavoritesUrl = "videoFavorite/loadUserVideoFavorites"
+
+/** 发送手机验证码 */
+public let sendIndetifyCodeUrl = "sendIndetifyCode"
+/** 验证手机验证码 */
+public let checkIndetifyCodeUrl = "checkIndetifyCode"
+/** 修改手机号 */
+public let updatePhoneUrl = "savePhone"
+/** 最热列表 */
+public let hotByCollectionIdUrl = "video/v2/loadHotVideosByCollectionId"
+/** 最新列表 */
+public let latelyByCollectionIdUrl = "video/v2/loadLatelyVideosByCollectionId"
+/** 自己喜欢列表 */
+public let favoriteUrl = "video/v2/favorite/list"
+/** 视频分享列表 */
+public let shareRecordListUrl = "video/shareRecordList"
+/** 关注某人 */
+public let followUrl = "user/follow"
+/** 取消关注某人 */
+public let unfollowUrl = "user/unfollow"
+/** 订阅某人 */
+public let subscribeUrl = "user/subscribe"
+/** 取消订阅某人 */
+public let unsubscribe = "user/unsubscribe"
+/** 收藏视频 */
+public let favoriteVideoUrl = "video/favorite"
+/** 视频详情 */
+public let videoDetailUrl = "video/v2/detail"
+/** 批量请求视频详情 */
+public let videosDetailUrl = "video/v2/appCache/detail"
+/** 发布视频 */
+public let videoSendUrl = "video/send"
+/** 修改视频 */
+public let updateVideoUrl = "video/updateVideo"
+/** 删除视频 */
+public let deleteVideoUrl = "video/deleteVideo"
+/// 获取视频封面
+public let vodeoCoverImageUrl = "video/getCoverImagePaths"
+
+/// 关注人列表
+public let followedSingleUrl = "user/followed/single"
+/// 关注视频列表
+public let attendtionUrl = "user/followed/list"
+/// 关注视频更新数量(小红点)
+public let attendtionInfoUrl = "user/followed/info"
+/** 取消收藏视频 */
+public let unfavoriteVideoUrl = "video/unfavorite"
+/** 关注人头像 */
+public let idolsUpdatedUrl = "user/idolsUpdated"
+/** 关注人卡片 */
+public let recommendUserCardUrl = "user/info/getRecommendUserCard"
+/** 关注人卡片不喜欢 */
+public let userCardunFollowUrl = "user/info/unFollowUid"
+/** 举报视频原因列表 */
+public let reportVideoListUrl = "video/report/reason/list"
+/** 举报用户原因列表 */
+public let reportUserListUrl = "user/info/report/reason/list"
+/** 举报某个视频 */
+public let reportVideoUrl = "video/report"
+/** 举报某个用户 */
+public let reportUserUrl = "user/info/report"
+/** 拉黑某个用户 */
+public let bannedUserUrl = "user/info/black"
+/** 取消拉黑某个用户 */
+public let unBannedUserUrl = "user/info/unBlack"
+/** 某个用户是否被拉黑 */
+public let isBannedUserUrl = "user/info/isBlack"
+/** 黑明单列表 */
+public let bannedUserListUrl = "user/info/blackList"
+/** 不感兴趣某个视频 */
+public let hateVideoUrl = "videoHated/hate"
+/** 获取分享h5页面 */
+public let h5ShareLinkUrl = "video/app/share/getVideoH5ShareLink"
+/** 获取分享微信好友数据 */
+public let wxFriendUrl = "video/app/share/getVideoAppShareWxFriendData"
+/** 视频播放上报 */
+public let reportPlayUrl = "measure/report/play"
+/** 系统设置 */
+public let systemConfigUrl = "sys/config"
+/** 系统设置(新) */
+public let systemAppConfigUrl = "sys/app/config"
+
+/**  取 APP 的常规配置参数 如推荐的10个标题 */
+public let getBaseConfigURL = "frontConfig/getBaseConfig"
+
+/** 用户协议 */
+public let cUserProtocol = "https://weapppiccdn.yishihui.com/resources/agreements/videoservice.html?type=\(BFConfig.shared.appType)"
+/** 隐私政策 */
+public let cPrivacy = "https://weapppiccdn.yishihui.com/resources/agreements/videoagreement.html?type=\(BFConfig.shared.appType)"
+/** 互联网管理规定 */
+public let cNetManagePrivacy = "http://www.cac.gov.cn/2017-08/25/c_1121541842.htm"
+// ***************** 埋点上报地址 **********************//
+public let downLoadUrl = "https://rescdn.yishihui.com/"
+// 记录播放的视频
+public let videoPlayReportUrl = "video/played"
+// 记录realPlay播放的视频
+public let videoRealPlayReportUrl = "video/realPlayed"
+// 记录刷过的视频
+public let videoViewReportUrl = "video/view"
+// 上报视频动作记录
+public let videoActionReportUrl = "video/videoActionReport"
+// 通用上报
+public let staticsFrontendReportUrl = "statistics/uploadLogFromFrontend"
+// 通用上报-行为上报
+public let staticsloadcLickReportUrl = "statistics/uploadcLickInfo"
+// 上传行为上报
+public let uploadOperationInfoReportUrl = "statistics/uploadOperationInfo"
+// 用户分享的上报
+public let userShareReportUrl = "user/share/report"
+// 上报分享视频给微信朋友的行为
+public let userShareFriendReportUrl = "video/shared/weixin/friend"
+// 上报分享视频给朋友圈的行为
+public let userShareH5ReportUrl = "video/shared/h5"
+
+// 推送点击上报
+public let pushActionReportUrl = "push/action/report"
+// 上报DeviceToken
+public let pushDeviceTokenReportUrl = "push/device/addOrUpdate"
+
+// ***************** 活动相关地址 **********************//
+
+// 参加活动
+public let payActivityMoneyUrl = "order/payActivityMoney"
+// 查询状态
+public let payOrderStatusUrl = "order/orderStatus"
+// 更新客户端状态
+public let updatePayStatusUrl = "order/updateClientPayStatus"
+// 活动入口&触达
+public let activityInfoUrl = "app/activity/getActivityInfo"
+// 立即报名
+public let joinActivityUrl = "app/activity/joinActivity"
+// 手动改变活动状态
+public let updateActivityStatusUrl = "app/activity/updateWxAppActivityByStatus"
+/// 邀请好友
+public let inviteFriendJoinUrl = "app/activity/inviteFriendJoin"
+
+// ***************** 搜索相关地址 **********************//
+
+// 搜索用户跟视频
+public let searchUserAndVideoUrl = "search/app/userandvideo/list"
+// 搜索用户
+public let searchUserUrl = "search/app/user/list"
+// 搜索视频
+public let searchVideoUrl = "search/app/video/list"
+// 热门视频
+public let searchHotVideoUrl = "search/app/hot/videos"
+// 热门词
+public let searchHotWordsUrl = "search/app/hot/words"
+// 搜索的上报
+public let searchReportUrl = "search/app/report"
+
+// ***************** 视频编辑相关地址 **********************//
+
+// 取发音人
+public let listAllVoicesUrl = "producevideo/voice/listAllVoices"
+
+// 收藏发音人
+public let favoriteVoiceUrl = "producevideo/voice/favoriteVoice"
+// 取消收藏发音人
+public let unFavoriteVoiceUrl = "producevideo/voice/unFavoriteVoice"
+// 试听文字语音
+public let listeningTextSpeechUrl = "producevideo/listeningTextSpeech"
+// 文字转语音
+public let sectionTextSpeechSynthesizeUrl = "producevideo/sectionTextSpeechSynthesize"
+// 取草稿箱列表
+public let listUserDraftboxUrl = "producevideo/draftbox/listUserDraftbox"
+
+// 取草稿箱信息
+public let draftboxGetSdataUrl = "producevideo/draftbox/getSdata"
+
+// 收藏列表
+public let listUserfavoriteVoicesUrl = "producevideo/voice/listUserfavoriteVoices"
+
+// 取nsl token
+public let getNlsAccessTokenUrl = "producevideo/voice/getNlsAccessToken"
+
+// 取发音人的详细信息
+public let getVoiceInfoUrl = "producevideo/voice/getVoiceInfo"
+
+// 获取所有引导视频
+public let guideVideosUrl = "producevideo/guide/listAllGuideVideos"
+// 获取背景音乐分类
+public let bgmCategoryListUrl = "producevideo/bgm/app/getAllBgmCates"
+// 获取某个分类下的背景音乐
+public let bgmListUrl = "producevideo/bgm/pageCateBgm"
+// 收藏背景音乐列表
+public let bgmFavoriteListUrl = "producevideo/bgm/listUserFavoriteBgms/v2"
+// 收藏某个背景音乐
+public let favoriteBGMUrl = "producevideo/bgm/favoriteBgm/v2"
+// 取消收藏某个背景音乐
+public let unFavoriteBGMUrl = "producevideo/bgm/unFavoriteBgm/v2"
+// 获取背景音乐信息
+public let getBgmInfoUrl = "producevideo/bgm/v2/getBgmInfo"
+
+/// 搜索素材推荐请求
+public let searchRecommendMaterialUrl = "v1/recommend/flow"
+/// 搜索素材请求
+public let searchMaterialUrl = "v1/search/flow"
+/// 搜索背景音乐
+public let searchBGMMaterialUrl = "music/search"
+// 取视频真地址如抖音
+public let getVideoAddressUrl = "v1/search/getVideoAddress"
+/// 通过md5查已上传的素材
+public let materialByContentMd5Url = "producevideo/material/getMaterialByContentMd5"
+/// 获取素材vod上传凭证
+public let materialUploadAuthUrl = "producevideo/material/createMaterialUploadAuth"
+/// 批量获取素材vod上传凭证
+public let batchMaterialUploadAuthUrl = "producevideo/material/batchCreateMaterialUploadAuth"
+/// 获取素材oss上传凭证
+public let materialUploadStsTokenUrl = "oss/producevideo/getStsToken"
+/// 保存素材
+public let saveMaterialUrl = "producevideo/material/saveMaterial"
+/// 音频素材转换成文字
+public let audioMaterialTransferTextUrl = "producevideo/material/audioMaterialTransferText"
+/// 素材所有者用户信息
+public let getMaterialOwnerUserInfoUrl = "producevideo/material/getMaterialOwnerUserInfo"
+
+/// 保存草稿箱
+public let saveDraftboxUrl = "producevideo/draftbox/save/v2"
+/// 删除草稿箱
+public let deleteDraftboxUrl = "producevideo/draftbox/delete"
+/// 批量删除草稿箱
+public let deleteMultiDraftboxUrl = "producevideo/draftbox/deleteMulti"
+/// 复制草稿箱
+public let copyDraftboxUrl = "producevideo/draftbox/copy"
+/// 修改草稿箱名称
+public let updateDraftboxTitleUrl = "producevideo/draftbox/updateTitle"
+/// 草稿箱数量
+public let draftboxUserCountUrl = "producevideo/draftbox/countUserDraftbox"
+/// 保存合成视频项目数据
+public let saveProjectUrl = "producevideo/saveProject"
+/// 更新合成视频项目数据
+public let updateProjectUrl = "producevideo/updateProject"
+/// 发布视频后上报
+public let reportSendVideoUrl = "producevideo/reportSendVideo"
+// 文本断句 URL  t1 to t2
+public let phraseSentenceURL = "producevideo/phraseSentence"
+// 再创作-从项目中复制草稿
+public let copyFromProjectURL = "producevideo/draftbox/copyFromProject"
+// 再创作视频列表
+public let listReproduceVideoURL = "producevideo/listReproduceVideo"
+
+// ***************** 站内消息相关地址 **********************//
+
+// 站内消息埋点上报
+public let messagePeportUrl = "message/report/station"
+// 消息未读数
+public let messageUnReadInfoUrl = "message/getUnReadInfo"
+// 常规消息列表
+public let messageNormalListUrl = "message/normal/list"
+// 删除消息
+public let messageDeleteUrl = "message/delete"
+// 常规消息已读
+public let messageNormalReadUrl = "message/normal/read"
+// 某种类型常规消息全部已读
+public let messageReadAllUrl = "message/normal/readAllByMsgType"
+// 分享空间消息列表
+public let messageShareSpaceListUrl = "message/sharespace/list"
+// 分享空间子类型消息列表
+public let messageShareSpaceSubListUrl = "message/sharespace/sub/list"
+/// 某条分享动态的子类型消息数量信息
+public let messageShareSpaceSubCountInfoUrl = "message/sharespace/getSubCountInfo"
+
+// 分享空间消息全部已读
+public let messageShareReadAllUrl = "message/sharespace/readAll"
+// 某条分享空间消息已读
+public let messageShareReadUrl = "message/sharespace/read"
+// 删除分享空间消息
+public let messageDeleteShareUrl = "message/sharespace/deleteRecord"
+// 分享空间某条动态的子类型消息全部已读
+public let messageReadAllBySubMsgTypeUrl = "message/sharespace/readAllBySubMsgType"
+// 分享空间某条动态的消息全部已读
+public let messageReadAllByShareIdUrl = "message/sharespace/readAllByShareId"
+
+// 某条分享动态的所有未读数 add by ak commentCount enjoinCount shareCount
+public let messageShareGetUnReadInfoUrl = "message/sharespace/getUnReadInfo"
+// 分享空间行为汇总数 API1
+public let messageSharespaceGetCountInfoUrl = "video/sharespace/app/getCountInfo"
+// 分享空间-评论列表 API1
+public let messagePageCommentRecordUrl = "video/sharespace/app/pageCommentRecord"
+// 分享空间-喜欢列表 API1
+public let messagePageFavoriteRecordUrl = "video/sharespace/app/pageFavoriteRecord"
+// 分享空间-播放列表 API1
+public let messagePagePlayRecordUrl = "video/sharespace/app/pagePlayRecord"
+// 分享空间-分享列表 API1
+public let messagePageShareRecordUrl = "video/sharespace/app/pageShareRecord"
+
+// ***************** 卡点视频相关地址 **********************//
+// 卡点音乐分类列表
+public let stuckPointMusicCategoryUrl = "producevideo/music/listRhythmMusicTag"
+// 卡点音乐某个分类下列表
+public let stuckPointMusicPageUrl = "producevideo/music/listRhythmMusic"
+// 获取某个音乐的卡点数据
+public let stuckPointMusicDetailUrl = "producevideo/music/getRhythmMusicData"
+// 获取项目的卡点音乐信息
+public let stuckPointProjectMusicInfoUrl = "producevideo/getProjectRhythmMusicInfo"
+
+// ***************** 广告相关地址 **********************//
+
+// 获取广告配置信息
+public let adPositionInfoUrl = "ad/position/info"
+// 意见反馈地址
+public let feedbackUrl = "https://support.qq.com/product/\(BFConfig.shared.txFeedbackAppId)"
+// 意见反馈主页
+public let feedbackPageUrl = "https://support.qq.com/embed/phone/\(BFConfig.shared.txFeedbackAppId)"
+
+
+// ***************** 激励相关地址 **********************//
+
+public let applyCheckUrl = "incentive/creator/applyCheck"
+public let applyStatusUrl = "incentive/creator/applyStatus"
+// 分享者用户权益中心
+public let incentiveUserRCenterUrl = "incentive/userRightCenter"
+// 加入分享者激励计划
+public let incentiveJoinUrl = "incentive/sharer/join"
+// 分享者激励计划邀请检查
+public let invitedCheckUrl = "incentive/sharer/invitedCheck"
+// 是否已无有效分享
+public let invitedShareStatusUrl = "incentive/sharer/shareCheck"
+
+
+// ***************** 评论相关地址 **********************//
+
+// 评论列表
+public let commendListUrl = "comment/app/page"
+// 二级评论列表
+public let commendSecondListUrl = "comment/second/page"
+// 保存一级评论
+public let saveTopCommendUrl = "comment/top/save"
+// 保存二级评论
+public let saveSecondCommendUrl = "comment/second/save"
+// 评论点赞或取消点赞
+public let commentPraiseUrl = "comment/praise"
+// 评论删除
+public let commentDeleteUrl = "comment/delete"
+// 评论举报
+public let commentReportUrl = "comment/report"
+
+
+// ***************** 话题相关地址 **********************//
+public let communityInitUrl = "community/init/feed"
+// 首页推荐Feed流
+public let communityRecommendUrl = "community/recommend/list"
+// 首页关注Feed流
+public let communityFollowingListUrl = "community/following/list"
+// 视频相关推荐
+public let communityRelatedListUrl = "community/recommend/relatedList"
+// 话题详情
+public let topicDetailUrl = "community/topic/detail"
+// 话题详情最热Feed流
+public let topicDeailHotlistUrl = "community/topic/content/hotlist"
+// 话题详情最新Feed流
+public let topicDeailNewlistUrl = "community/topic/content/newlist"
+// 用户创建话题
+public let topicCreateUrl = "community/topic/create"
+// 热门话题
+public let topicHotlistUrl = "community/topic/hotlist"
+// 我加入的话题 视频列表
+public let topicMySubListUrl = "community/topic/mySubscribedList"
+// 话题推荐(新用户弹窗)
+public let topicRecommendUrl = "community/topic/recommend"
+// 话题推荐(发布页)
+public let topicRecoPublishUrl = "community/topic/recommendForPublish"
+// 搜索话题
+public let topicSearchUrl = "community/topic/search"
+// 加入话题(订阅话题)
+public let topicSubscribeUrl = "community/topic/subscribe"
+// 退出话题(取消订阅话题)
+public let topicUnSubscribeUrl = "community/topic/unsubscribe"
+// 信息收集
+public let personalizedUrl = "community/user/personalized/saveUserPersonalizedInfo"
+// 关注/我加入话题更新数
+public let updateNumberUrl = "community/tips/updateNumber"