<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Condy</title>
    <description>The latest articles on DEV Community by Condy (@yangkj).</description>
    <link>https://dev.to/yangkj</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F808715%2Fc46b96e6-bafe-4e8b-9449-512bef3f44b4.jpeg</url>
      <title>DEV Community: Condy</title>
      <link>https://dev.to/yangkj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yangkj"/>
    <language>en</language>
    <item>
      <title>🚀 Harbeth: High-Performance Swift Image Processing Library</title>
      <dc:creator>Condy</dc:creator>
      <pubDate>Sat, 28 Mar 2026 03:39:55 +0000</pubDate>
      <link>https://dev.to/yangkj/harbeth-high-performance-swift-image-processing-library-4m25</link>
      <guid>https://dev.to/yangkj/harbeth-high-performance-swift-image-processing-library-4m25</guid>
      <description>&lt;h1&gt;
  
  
  🚀 Harbeth: High-Performance Swift Image Processing Library
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3s1c03x16btcegvgy6k6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3s1c03x16btcegvgy6k6.gif" alt="Harbeth Banner" width="540" height="960"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Journey Behind Harbeth
&lt;/h2&gt;

&lt;p&gt;As an iOS/macOS developer, I've always been fascinated by the power of GPU-accelerated image processing. After working with various libraries and facing performance bottlenecks in real-time applications, I decided to create Harbeth - a library that combines the best of Metal performance with an intuitive Swift API.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Challenges I Faced
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance Limitations&lt;/strong&gt;: Existing solutions either lacked performance or had complex APIs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-Platform Consistency&lt;/strong&gt;: Ensuring the same code worked seamlessly across iOS, macOS, tvOS, and watchOS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory Management&lt;/strong&gt;: Optimizing texture usage to avoid memory spikes during real-time processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Design&lt;/strong&gt;: Creating an intuitive interface that hides the complexity of Metal while providing full control&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What Makes Harbeth Special
&lt;/h3&gt;

&lt;p&gt;After months of development and optimization, Harbeth has become a library that I'm truly proud of. Let me share what makes it stand out:&lt;/p&gt;

&lt;h2&gt;
  
  
  🎨 Technical Deep Dive
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Metal-Powered Architecture
&lt;/h3&gt;

&lt;p&gt;Harbeth is built on a layered architecture that maximizes Metal's capabilities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Core rendering pipeline&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;C7RenderPipeline&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;device&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;MTLDevice&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;commandQueue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;MTLCommandQueue&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;library&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;MTLLibrary&lt;/span&gt;

    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;C7FilterProtocol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;inputTexture&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;MTLTexture&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;MTLTexture&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 1. Create render pass descriptor&lt;/span&gt;
        &lt;span class="c1"&gt;// 2. Set up command buffer&lt;/span&gt;
        &lt;span class="c1"&gt;// 3. Encode render commands&lt;/span&gt;
        &lt;span class="c1"&gt;// 4. Execute and return output texture&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Smart Texture Pooling
&lt;/h3&gt;

&lt;p&gt;One of the key optimizations is the texture pool system, which dramatically reduces memory allocation overhead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;TexturePool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;textureCache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;TextureKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;MTLTexture&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[:]&lt;/span&gt;

    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;getTexture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pixelFormat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;MTLPixelFormat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;MTLTexture&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Check cache first&lt;/span&gt;
        &lt;span class="c1"&gt;// Create new texture if needed&lt;/span&gt;
        &lt;span class="c1"&gt;// Return texture for use&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;returnTexture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;texture&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;MTLTexture&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Return texture to cache for reuse&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Real-time Performance Monitoring
&lt;/h3&gt;

&lt;p&gt;Harbeth includes a built-in performance monitoring system that helps identify bottlenecks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Enable performance monitoring&lt;/span&gt;
&lt;span class="kt"&gt;Device&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEnablePerformanceMonitor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Process with HarbethIO&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;io&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;HarbethIO&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;element&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;output&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// Get performance statistics&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;PerformanceMonitor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getStatistics&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Total Time: &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;totalTime&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;ms | GPU Time: &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gpuTime&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;ms"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🚀 Advanced Usage Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Creating Custom Filters
&lt;/h3&gt;

&lt;p&gt;Harbeth makes it easy to create custom filters using Metal shaders:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;C7CustomFilter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;C7FilterProtocol&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;modifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Modifier&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;kernel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"customKernel"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Custom parameters&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;intensity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;

    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;setupSpecialEncodeCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;encoder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;MTLComputeCommandEncoder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;encoder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;intensity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;MemoryLayout&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Float&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;stride&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Metal shader (customKernel.metal)&lt;/span&gt;
&lt;span class="cm"&gt;/*
kernel void customKernel(
    texture2d&amp;lt;half, access::read&amp;gt; input [[texture(0)]],
    texture2d&amp;lt;half, access::write&amp;gt; output [[texture(1)]],
    constant float &amp;amp;intensity [[buffer(0)]],
    uint2 gid [[thread_position_in_grid]]
) {
    half4 color = input.read(gid);
    // Custom processing
    color.rgb = mix(color.rgb, half3(1.0), intensity);
    output.write(color, gid);
}
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Complex Filter Chains
&lt;/h3&gt;

&lt;p&gt;Combine multiple filters for sophisticated effects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create a cinematic effect chain&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;cinematicFilter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;C7CombinationCinematic&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// Or build your own custom chain&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;C7FilterProtocol&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="kt"&gt;C7Brightness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;brightness&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="kt"&gt;C7Contrast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;contrast&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="kt"&gt;C7Saturation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;saturation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="kt"&gt;C7Vignette&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;intensity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="kt"&gt;C7Granularity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;grain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;// Apply with operator chaining&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;filters&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Real-time Camera Processing
&lt;/h3&gt;

&lt;p&gt;Process camera feed with filters at 60 FPS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Setup camera collector&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;camera&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;C7CollectorCamera&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;delegate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;camera&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;captureSession&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sessionPreset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hd1280x720&lt;/span&gt;

&lt;span class="c1"&gt;// Apply real-time filters&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;filters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;C7EdgeGlow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;lineColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;red&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="n"&gt;camera&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filters&lt;/span&gt;

&lt;span class="c1"&gt;// Start capture&lt;/span&gt;
&lt;span class="n"&gt;camera&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startRunning&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// Handle filtered frames&lt;/span&gt;
&lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="kt"&gt;CameraViewController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;C7CollectorImageDelegate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;preview&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;collector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;C7Collector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fliter&lt;/span&gt; &lt;span class="nv"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;C7Image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Update UI with filtered image&lt;/span&gt;
        &lt;span class="kt"&gt;DispatchQueue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;imageView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📊 Performance Breakdown
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4awoij5bhlfz306hvesm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4awoij5bhlfz306hvesm.png" alt="Performance Chart" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Performance Insights
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GPU Acceleration&lt;/strong&gt;: Up to 5x faster than CPU processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: GPU time grows logarithmically while CPU time grows linearly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory Efficiency&lt;/strong&gt;: Texture pooling reduces memory usage by up to 70%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time Capability&lt;/strong&gt;: Maintain 60 FPS even with 10+ filters&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  💻 macOS-specific Features
&lt;/h2&gt;

&lt;p&gt;Harbeth includes several macOS-specific optimizations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AppKit Integration&lt;/strong&gt;: Seamless integration with NSImage and AppKit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High-Resolution Support&lt;/strong&gt;: Optimized for Retina displays&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-window Processing&lt;/strong&gt;: Handle multiple images across different windows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drag &amp;amp; Drop Support&lt;/strong&gt;: Easy integration with macOS drag and drop
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// macOS-specific implementation&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;MacImageProcessor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;processDroppedImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;NSImage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;filters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;C7ColorMatrix4x4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sepia&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;// Update UI with result&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🎨 SwiftUI Integration
&lt;/h2&gt;

&lt;p&gt;Harbeth provides native SwiftUI support with the &lt;code&gt;HarbethView&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SwiftUI&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Harbeth&lt;/span&gt;

&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;FilteredImageView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;@State&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;inputImage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UIImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;named&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"sample"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
    &lt;span class="kd"&gt;@State&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;intensity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;VStack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;HarbethView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inputImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="kt"&gt;CIHighlight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;highlight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;intensity&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="kt"&gt;C7WaterRipple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ripple&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;intensity&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
                &lt;span class="n"&gt;image&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resizable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;aspectRatio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;contentMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cornerRadius&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="kt"&gt;Slider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;$intensity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🌟 Use Cases and Success Stories
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Camera Apps
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-time filters&lt;/strong&gt; during capture&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Beauty effects&lt;/strong&gt; with skin smoothing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Creative filters&lt;/strong&gt; for social media&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Photo Editors
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Professional color grading&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch processing&lt;/strong&gt; of multiple images&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Artistic effects&lt;/strong&gt; and stylization&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Video Processing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Filtered video playback&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time effects&lt;/strong&gt; during recording&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Video enhancement&lt;/strong&gt; and color correction&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📚 Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;CocoaPods:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;pod&lt;/span&gt; &lt;span class="s1"&gt;'Harbeth'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Swift Package Manager:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="nv"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"https://github.com/yangKJ/Harbeth.git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"master"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Quick Start
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Harbeth&lt;/span&gt;

&lt;span class="c1"&gt;// Method 1: HarbethIO&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;io&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;HarbethIO&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;element&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;C7SoulOut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;soul&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;output&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// Method 2: Direct extension&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;C7SoulOut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;soul&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;

&lt;span class="c1"&gt;// Method 3: Operator chaining&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;C7SoulOut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;soul&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🤔 Common Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Q: How does Harbeth compare to CoreImage?&lt;/strong&gt;&lt;br&gt;
A: Harbeth offers better performance for complex filter chains and a more intuitive API, while still integrating with CoreImage for additional functionality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Can I use Harbeth in production?&lt;/strong&gt;&lt;br&gt;
A: Yes, Harbeth is production-ready and used in several apps. It's stable, well-documented, and actively maintained.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: How do I handle memory constraints?&lt;/strong&gt;&lt;br&gt;
A: Harbeth includes automatic texture pooling and memory management. For memory-constrained devices, use &lt;code&gt;Device.setMemoryLimitMB()&lt;/code&gt; to set appropriate limits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Does Harbeth support live camera processing?&lt;/strong&gt;&lt;br&gt;
A: Yes, Harbeth provides &lt;code&gt;C7CollectorCamera&lt;/code&gt; for real-time camera processing with filters applied at 60 FPS.&lt;/p&gt;

&lt;h2&gt;
  
  
  📞 Support and Community
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Repository&lt;/strong&gt;: &lt;a href="https://github.com/yangKJ/Harbeth" rel="noopener noreferrer"&gt;https://github.com/yangKJ/Harbeth&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Discussions&lt;/strong&gt;: &lt;a href="https://github.com/yangKJ/Harbeth/discussions" rel="noopener noreferrer"&gt;Discuss Harbeth&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Issues&lt;/strong&gt;: &lt;a href="https://github.com/yangKJ/Harbeth/issues" rel="noopener noreferrer"&gt;Bug reports and feature requests&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎯 Future Roadmap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;More filters&lt;/strong&gt; and effects&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enhanced Metal Shader support&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Machine learning integration&lt;/strong&gt; for advanced effects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved documentation&lt;/strong&gt; and examples&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community contributions&lt;/strong&gt; and plugin system&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Have you used Harbeth in your projects? I'd love to hear about your experiences and see what creative effects you've created. Let's push the boundaries of image processing together!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ios</category>
      <category>performance</category>
      <category>showdev</category>
      <category>swift</category>
    </item>
    <item>
      <title>Harbeth: A high performance Metal image &amp; video filter library for Swift</title>
      <dc:creator>Condy</dc:creator>
      <pubDate>Fri, 20 Mar 2026 04:12:50 +0000</pubDate>
      <link>https://dev.to/yangkj/harbeth-a-high-performance-metal-image-video-filter-library-for-swift-3m3a</link>
      <guid>https://dev.to/yangkj/harbeth-a-high-performance-metal-image-video-filter-library-for-swift-3m3a</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/yangKJ/Harbeth" rel="noopener noreferrer"&gt;&lt;strong&gt;Harbeth&lt;/strong&gt;&lt;/a&gt; is a high-performance Swift library focused on GPU-accelerated real-time image processing, camera capture, and video processing. Built on Metal technology, it also integrates with CoreImage and Metal Performance Shaders, providing developers with a powerful and easy-to-integrate image processing solution.&lt;/p&gt;




&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;🟣 Harbeth offers a comprehensive set of features designed to make image and video processing fast, efficient, and easy to implement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cross-Platform Support&lt;/strong&gt;: Runs seamlessly on iOS, macOS, tvOS, and watchOS, supporting both UIKit/AppKit and SwiftUI frameworks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versatile Input Sources&lt;/strong&gt;: Apply filters to a wide range of image and video sources including MTLTexture, UIImage, NSImage, CIImage, CGImage, CMSampleBuffer, and CVPixelBuffer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rich Filter Ecosystem&lt;/strong&gt;: Over 200+ built-in filters organized into intuitive categories, covering everything from basic color adjustments to advanced artistic effects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced Integration&lt;/strong&gt;: Leverage the power of &lt;a href="https://github.com/yangKJ/Harbeth/tree/master/Sources/MPS" rel="noopener noreferrer"&gt;Metal Performance Shaders (MPS)&lt;/a&gt; for high-performance filtering, while maintaining compatibility with &lt;a href="https://github.com/yangKJ/Harbeth/tree/master/Sources/CoreImage" rel="noopener noreferrer"&gt;CoreImage&lt;/a&gt; filters for maximum flexibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metal-Powered Rendering&lt;/strong&gt;: All previews and rendering operations are accelerated by Metal, ensuring smooth, real-time performance even with complex filter chains.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Filter Support&lt;/strong&gt;: Easily create and integrate custom filters using LUTs has &lt;a href="https://github.com/yangKJ/Harbeth/tree/master/Sources/Compute/Lookup%20Tables/C7LookupTable1D.swift" rel="noopener noreferrer"&gt;1D Lookup Tables&lt;/a&gt;、&lt;a href="https://github.com/yangKJ/Harbeth/tree/master/Sources/Compute/Lookup%20Tables/C7LookupTable.swift" rel="noopener noreferrer"&gt;2D Lookup Tables&lt;/a&gt;、 &lt;a href="https://github.com/yangKJ/Harbeth/tree/master/Sources/Compute/Lookup%20Tables/C7ColorCube.swift" rel="noopener noreferrer"&gt;3D Cube Files&lt;/a&gt;, And &lt;a href="https://github.com/yangKJ/Harbeth/tree/master/Sources/Compute/Lookup%20Tables/C7MultiZoneLookup.swift" rel="noopener noreferrer"&gt;Multi Zone Tables&lt;/a&gt;, or custom Metal shaders. Create advanced combination filters by subclassing &lt;code&gt;C7CombinationBase&lt;/code&gt; for complex, multi-step effects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-Time Processing&lt;/strong&gt;: Achieve smooth, real-time camera capture and video playback with live filter application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Video Processing&lt;/strong&gt;: Seamlessly process both local and network video files using the integrated &lt;a href="https://github.com/yangKJ/Kakapos" rel="noopener noreferrer"&gt;Kakapos&lt;/a&gt; library.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intuitive API&lt;/strong&gt;: Enjoy a clean, Swift-friendly API with chainable filter operations and operator overloading for concise, expressive code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Optimization&lt;/strong&gt;: Benefit from automatic texture pooling, memory management, and multi-encoder support for optimal performance across devices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensive Documentation&lt;/strong&gt;: Comprehensive documentation and demo projects to help you get started quickly and make the most of Harbeth's capabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SwiftUI integration&lt;/strong&gt;: Native support for SwiftUI framework.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🎨 Filter System
&lt;/h3&gt;

&lt;p&gt;Harbeth offers a comprehensive filter classification to meet various image processing needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Color Adjustment&lt;/strong&gt;: Brightness, contrast, saturation, exposure, white balance, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blur Effects&lt;/strong&gt;: Gaussian blur, bilateral blur, motion blur, zoom blur, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blend Modes&lt;/strong&gt;: Normal, multiply, screen, overlay, hard light, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edge &amp;amp; Detail&lt;/strong&gt;: Sharpen, edge detection, sketch, comic strip effect, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distortion &amp;amp; Warp&lt;/strong&gt;: Bulge, pinch, swirl, water ripple, glass sphere, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stylization&lt;/strong&gt;: Oil painting, cartoon, glitch effect, split screen, soul out, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Geometric Transform&lt;/strong&gt;: Crop, flip, rotate, resize, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Matrix Processing&lt;/strong&gt;: 3x3 convolution matrix, 4x4 color matrix, 4x5 color matrix, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Utility&lt;/strong&gt;: Chroma key, highlight shadow, levels, luminance threshold, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generators&lt;/strong&gt;: Solid color, color gradient, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lookup Tables&lt;/strong&gt;: LUT-based color adjustments and CUBE file support.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blit Operations&lt;/strong&gt;: Copy region, crop, generate mipmaps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CoreImage Integration&lt;/strong&gt;: Access to CoreImage filters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metal Performance Shaders&lt;/strong&gt;: High-performance MPS filters&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;A total of 200+ kinds of built-in filters are currently available.✌️&lt;/strong&gt;
&lt;/h4&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;iOS Target&lt;/th&gt;
&lt;th&gt;macOS Target&lt;/th&gt;
&lt;th&gt;Xcode Version&lt;/th&gt;
&lt;th&gt;Swift Version&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;iOS 10.0+&lt;/td&gt;
&lt;td&gt;macOS 10.13+&lt;/td&gt;
&lt;td&gt;Xcode 10.0+&lt;/td&gt;
&lt;td&gt;Swift 5.0+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FyangKJ%2FHarbeth%2Fmaster%2FScreenshot%2FShiftGlitch.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FyangKJ%2FHarbeth%2Fmaster%2FScreenshot%2FShiftGlitch.gif" width="640" height="358"&gt;&lt;/a&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FyangKJ%2FHarbeth%2Fmaster%2FScreenshot%2FEdgeGlow.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FyangKJ%2FHarbeth%2Fmaster%2FScreenshot%2FEdgeGlow.gif" width="640" height="359"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Image
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🎷 Code zero intrusion add filter function for image.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;filter1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;C7ColorMatrix4x4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Matrix4x4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sepia&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;filter2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;C7Granularity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;grain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;filter3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;C7SoulOut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;soul&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;filters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;filter1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filter2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filter3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;// Use:&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;dest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;HarbethIO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;element&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;originImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Synchronize do something..&lt;/span&gt;
&lt;span class="kt"&gt;ImageView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;dest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;output&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// OR Use:&lt;/span&gt;
&lt;span class="kt"&gt;ImageView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;originImage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;makeGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// OR Use:&lt;/span&gt;
&lt;span class="kt"&gt;ImageView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;originImage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filtering&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filter1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filter2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filter3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// OR Use Operator:&lt;/span&gt;
&lt;span class="kt"&gt;ImageView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;originImage&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;filter1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;filter2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;filter3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Asynchronous do something..&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This performance is the best. 🚗🚗&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;dest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;HarbethIO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;element&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="nv"&gt;Source&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="nv"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;dest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transmitOutput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;weak&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="c1"&gt;// do something..&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Camera
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;📸 Camera capture generates pictures.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Add an edge detection filter:&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;C7EdgeGlow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;lineColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;red&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Generate camera collector:&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;camera&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;C7CollectorCamera&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;delegate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;camera&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;captureSession&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sessionPreset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;AVCaptureSession&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Preset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hd1280x720&lt;/span&gt;
&lt;span class="n"&gt;camera&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="kt"&gt;CameraViewController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;C7CollectorImageDelegate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;preview&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;collector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;C7Collector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fliter&lt;/span&gt; &lt;span class="nv"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;C7Image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// do something..&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Video
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;📺 Local video or Network video are simply apply with filters.

&lt;ul&gt;
&lt;li&gt;🙄 For details, See &lt;a href="https://github.com/yangKJ/Harbeth/blob/master/Demo/Harbeth-iOS-Demo/Modules/PlayerViewController.swift" rel="noopener noreferrer"&gt;PlayerViewController&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;You can also extend this by using &lt;a href="https://github.com/yangKJ/Harbeth/blob/master/Sources/Basic/Outputs/HarbethIO.swift" rel="noopener noreferrer"&gt;HarbethIO&lt;/a&gt; to filter the collected &lt;code&gt;CVPixelBuffer&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;lazy&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;video&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;C7CollectorVideo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;videoURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;string&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Link"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;asset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;AVURLAsset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;videoURL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;playerItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;AVPlayerItem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;asset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;asset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;AVPlayer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;playerItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;playerItem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;video&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;C7CollectorVideo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;player&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;delegate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;C7ColorMatrix4x4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Matrix4x4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sepia&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;video&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;video&lt;/span&gt;
&lt;span class="p"&gt;}()&lt;/span&gt;

&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;video&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;play&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="kt"&gt;PlayerViewController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;C7CollectorImageDelegate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;preview&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;collector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;C7Collector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fliter&lt;/span&gt; &lt;span class="nv"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;C7Image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// do something..&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  SwiftUI Support
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;For the direct use &lt;a href="https://github.com/yangKJ/Harbeth/blob/master/Sources/SwiftUI/HarbethView.swift" rel="noopener noreferrer"&gt;HarbethView&lt;/a&gt;, it is just a simple implementation.&lt;/li&gt;
&lt;li&gt;The SwiftUI API is still in-progress and may not be production ready. We're looking for help! 🤲
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;C7FilterProtocol&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="kt"&gt;CIHighlight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;highlight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;intensity&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="kt"&gt;C7WaterRipple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ripple&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;intensity&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kt"&gt;HarbethView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inputImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resizable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;aspectRatio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;contentMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🎨 Filter List
&lt;/h3&gt;

&lt;h4&gt;
  
  
  🔗 Combination Filters
&lt;/h4&gt;

&lt;p&gt;Combination filters allow you to create complex effects by combining multiple individual filters. These filters are designed to work together to achieve specific visual styles or effects that would be difficult to create with a single filter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages of Combination Filters:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplified Usage&lt;/strong&gt;: Apply multiple effects with a single filter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimized Performance&lt;/strong&gt;: Filters are applied in a single pass when possible&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent Results&lt;/strong&gt;: Pre-configured combinations ensure predictable outcomes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizable&lt;/strong&gt;: Many combination filters allow adjustment of individual parameters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Examples of Combination Filters:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7CombinationBeautiful&lt;/strong&gt;: Enhances facial features and skin tone for beauty effects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CombinationCinematic&lt;/strong&gt;: Creates a cinematic look with enhanced contrast and color grading&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CombinationColorGrading&lt;/strong&gt;: Professional color grading with temperature, tint, and tone adjustments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CombinationCreativeAtmosphere&lt;/strong&gt;: Adds creative atmosphere effects like warm glow, cool blue, golden hour, and moody&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CombinationCyberpunk&lt;/strong&gt;: Creates a cyberpunk style with neon glow, color shifting, and edge detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CombinationDreamy&lt;/strong&gt;: Achieves a dreamy, soft look with Gaussian blur, warmth, and reduced saturation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CombinationFilmSimulation&lt;/strong&gt;: Simulates modern film effects with grain and color characteristics&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CombinationHDRBoost&lt;/strong&gt;: Enhances dynamic range with improved highlight and shadow details&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CombinationModernHDR&lt;/strong&gt;: Achieves modern HDR effects with improved dynamic range&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CombinationVintage&lt;/strong&gt;: Applies vintage film effects with warm tones and grain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CombinationVintageFilm&lt;/strong&gt;: Simulates vintage film stock with grain, vignette, and sepia tone effects&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🎨 Color Adjustment
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7Brightness&lt;/strong&gt;: Adjusts the overall brightness of the image, with values ranging from -1.0 (darkest) to 1.0 (brightest), where 0.0 represents the original image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7ColorConvert&lt;/strong&gt;: Converts colors between different color spaces, such as RGB to YUV or other color space transformations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7ColorRGBA&lt;/strong&gt;: Independently adjusts the red, green, blue, and alpha channels of the image, allowing for precise color control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7ColorSpace&lt;/strong&gt;: Performs advanced color space operations, enabling complex color manipulations and transformations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Contrast&lt;/strong&gt;: Adjusts the contrast of the image, with values ranging from 0.0 (no contrast) to 2.0 (maximum contrast), where 1.0 is the original image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Curves&lt;/strong&gt;: Allows precise adjustment of the image's tonal curve, providing detailed control over brightness and contrast across different tonal ranges&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Exposure&lt;/strong&gt;: Simulates camera exposure adjustments, with values ranging from -10.0 (underexposed) to 10.0 (overexposed), where 0.0 is the original exposure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7FalseColor&lt;/strong&gt;: Uses the luminance values of the original image to mix between two user-specified colors, creating artistic false color effects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Gamma&lt;/strong&gt;: Applies gamma correction to the image, with values ranging from 0.0 (high contrast) to 3.0 (low contrast), where 1.0 is the original image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Grayed&lt;/strong&gt;: Converts the image to grayscale, removing all color information while preserving luminance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Haze&lt;/strong&gt;: Applies a haze effect to the image, reducing contrast and adding a foggy or misty appearance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7HSL&lt;/strong&gt;: Adjusts the hue, saturation, and lightness of the image independently, providing comprehensive color control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Hue&lt;/strong&gt;: Adjusts the overall hue of the image in degrees, rotating the color wheel to shift all colors uniformly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7LuminanceAdaptiveContrast&lt;/strong&gt;: Dynamically adjusts contrast based on local pixel brightness, enhancing details in both dark and bright areas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Monochrome&lt;/strong&gt;: Converts the image to a monochrome version, tinting it with a specific color based on the brightness of each pixel&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Nostalgic&lt;/strong&gt;: Applies a nostalgic color tone effect, reminiscent of vintage photographs with warm, aged colors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Opacity&lt;/strong&gt;: Adjusts the transparency of the image, making it more or less see-through&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Posterize&lt;/strong&gt;: Reduces the number of colors in the image, creating a stylized, poster-like effect with distinct color blocks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Saturation&lt;/strong&gt;: Adjusts the color saturation of the image, with values ranging from 0.0 (grayscale) to 2.0 (highly saturated), where 1.0 is the original image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Sepia&lt;/strong&gt;: Applies a sepia tone effect to the image, giving it a warm, brownish vintage appearance similar to old photographs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Vibrance&lt;/strong&gt;: Intelligently adjusts the vibrance of the image, enhancing muted colors while preserving skin tones, with values ranging from -1.2 (desaturated) to 1.2 (highly vibrant)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Temperature&lt;/strong&gt;: Adjusts the color temperature, tint, and color shift of the image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Warmth&lt;/strong&gt;: Adjusts the color temperature of the image, with values ranging from -1.0 (cooler) to 1.0 (warmer)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7WhiteBalance&lt;/strong&gt;: Adjusts the white balance of the image based on color temperature, allowing correction of color casts from different lighting conditions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7ColorCorrection&lt;/strong&gt;: Comprehensive color correction filter with levels, curves, and color balance controls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7AppleLogDecode&lt;/strong&gt;: Decodes Apple Log encoded images to linear space, used for processing HDR content&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🌫️ Blur Effects
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7BilateralBlur&lt;/strong&gt;: Applies a bilateral blur effect that preserves edges while blurring flat areas, creating a smooth appearance without losing important details&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CircleBlur&lt;/strong&gt;: Creates a circular blur effect that radiates from a central point, with blur intensity decreasing outward from the center&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7DetailPreservingBlur&lt;/strong&gt;: Applies a blur that reduces noise and smooths the image while preserving important details and edges&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7GaussianBlur&lt;/strong&gt;: Applies a classic Gaussian blur effect, creating a smooth, natural-looking blur by averaging pixel values with a Gaussian distribution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7MeanBlur&lt;/strong&gt;: Applies a mean (box) blur effect, averaging pixel values within the blur radius for a simple but effective blur&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7MotionBlur&lt;/strong&gt;: Simulates motion blur in a specified direction, creating the illusion of movement or camera shake&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7RedMonochromeBlur&lt;/strong&gt;: Applies a blur effect that affects only the red channel while converting the rest of the image to monochrome&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7TiltShift&lt;/strong&gt;: Applies a tilt-shift effect, creating a selective focus area with blur outside the focus region, simulating the shallow depth of field of tilt-shift lenses&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7ZoomBlur&lt;/strong&gt;: Creates a zoom blur effect that simulates the camera zooming in or out, with radial blur lines emanating from a central point&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🔄 Blend Modes
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7Blend&lt;/strong&gt;: Base class for all blend modes, providing common functionality for blending operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendChromaKey&lt;/strong&gt;: Implements chroma key (green screen) functionality, allowing replacement of a specific color with another image or transparency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendColorAdd&lt;/strong&gt;: Adds the color values of the blend layer to the base layer, resulting in a brighter image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendColorAlpha&lt;/strong&gt;: Blends layers based on the alpha channel values, creating semi-transparent effects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendColorBurn&lt;/strong&gt;: Darkens the base layer by increasing contrast, creating a rich, dark blending effect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendColorDodge&lt;/strong&gt;: Brightens the base layer by decreasing contrast, creating a lightening effect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendDarken&lt;/strong&gt;: Keeps the darker pixel values from either layer, resulting in an overall darker image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendDifference&lt;/strong&gt;: Subtracts the darker color from the lighter one, creating a high-contrast effect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendDissolve&lt;/strong&gt;: Randomly replaces pixels from the base layer with pixels from the blend layer, creating a dissolve effect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendDivide&lt;/strong&gt;: Divides the base layer colors by the blend layer colors, resulting in a brighter image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendExclusion&lt;/strong&gt;: Similar to difference mode but with lower contrast, creating a softer effect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendHardLight&lt;/strong&gt;: Combines multiply and screen modes, creating a strong lighting effect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendHue&lt;/strong&gt;: Uses the hue of the blend layer with the saturation and luminance of the base layer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendLighten&lt;/strong&gt;: Keeps the lighter pixel values from either layer, resulting in an overall brighter image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendLinearBurn&lt;/strong&gt;: Linearly darkens the base layer by the blend layer values&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendLuminosity&lt;/strong&gt;: Uses the luminance of the blend layer with the hue and saturation of the base layer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendMask&lt;/strong&gt;: Uses a mask to control which areas of the blend layer are visible&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendMultiply&lt;/strong&gt;: Multiplies the color values of the two layers, resulting in a darker image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendNormal&lt;/strong&gt;: The standard blending mode where the blend layer simply covers the base layer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendOverlay&lt;/strong&gt;: Combines multiply and screen modes, enhancing contrast while preserving highlights and shadows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendScreen&lt;/strong&gt;: Inverts both layers, multiplies them, then inverts the result, creating a lighter image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendSoftLight&lt;/strong&gt;: Gently lightens or darkens the base layer based on the blend layer values&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendSourceOver&lt;/strong&gt;: The default blending mode where the blend layer is drawn over the base layer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendSubtract&lt;/strong&gt;: Subtracts the blend layer colors from the base layer colors, resulting in a darker image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7BlendWithMask&lt;/strong&gt;: Uses a separate mask texture to control the blending of two layers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7ColorBurnEnhancedBlend&lt;/strong&gt;: Enhanced color burn blend mode&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7XORBlendWithMask&lt;/strong&gt;: XOR hybrid filter is used to achieve the effect of odd and even&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🔍 Edge &amp;amp; Detail
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7Canny&lt;/strong&gt;: Applies the Canny edge detection algorithm, a multi-stage process that identifies edges with high accuracy and low noise&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Clarity&lt;/strong&gt;: Enhances the clarity of the image by increasing contrast in midtones, making details more pronounced without amplifying noise&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7ComicStrip&lt;/strong&gt;: Creates a comic strip effect, with bold outlines and flat colors reminiscent of comic book art&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Crosshatch&lt;/strong&gt;: Applies a crosshatch pattern to the image, creating a sketch-like appearance with intersecting lines&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7DetailEnhancer&lt;/strong&gt;: Enhances fine details in the image without amplifying noise, resulting in a sharper appearance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7EdgeAwareSharpen&lt;/strong&gt;: Sharpens only the edge areas of the image while preserving smooth regions, avoiding the amplification of noise&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Granularity&lt;/strong&gt;: Adjusts the film graininess of the image, adding or reducing texture for a more cinematic or vintage appearance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Sharpen&lt;/strong&gt;: Sharpens the entire image by increasing contrast at edges, making details more pronounced&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7SharpenDetail&lt;/strong&gt;: Comprehensive sharpening filter combining sharpen, clarity, and detail enhancement for professional image sharpening&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Sketch&lt;/strong&gt;: Converts the image into a pencil sketch effect, emphasizing edges and reducing color information&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Sobel&lt;/strong&gt;: Applies the Sobel edge detection algorithm, which calculates gradients to identify edges in the image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7ThresholdSketch&lt;/strong&gt;: Creates a sketch effect using edge detection with thresholding, resulting in a high-contrast, line-based representation&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🌀 Distortion &amp;amp; Warp
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7Bulge&lt;/strong&gt;: Creates a bulge distortion effect that pushes pixels outward from a central point, creating a convex appearance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7ColorCGASpace&lt;/strong&gt;: Applies a CGA (Color Graphics Adapter) color space effect, limiting colors to a palette of 16 colors for a retro computer appearance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7ColorPacking&lt;/strong&gt;: Applies a color packing effect that reduces color depth, creating a stylized, low-color appearance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Fluctuate&lt;/strong&gt;: Creates a fluctuation effect that distorts the image in a wavelike pattern, similar to a heat haze or water distortion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7GlassSphere&lt;/strong&gt;: Simulates the effect of looking through a glass sphere, combining refraction and reflection for a spherical distortion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Halftone&lt;/strong&gt;: Creates a halftone printing effect, replacing continuous tones with dots of varying size and density&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Morphology&lt;/strong&gt;: Applies morphological operations such as erosion and dilation, useful for edge detection and noise reduction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Pinch&lt;/strong&gt;: Creates a pinch distortion effect that pulls pixels inward toward a central point, creating a concave appearance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Pixellated&lt;/strong&gt;: Applies a pixelation effect, reducing the image resolution to create large, visible pixels&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7PolarPixellate&lt;/strong&gt;: Converts the image to polar coordinates and applies pixelation, creating a circular, distorted appearance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7PolkaDot&lt;/strong&gt;: Overlays a polka dot pattern on the image, replacing pixels with dots of varying size and color&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7SphereRefraction&lt;/strong&gt;: Simulates light refraction through a sphere, creating a distorted view of the image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Swirl&lt;/strong&gt;: Creates a swirl distortion effect that rotates pixels around a central point, creating a vortex appearance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7WaterRipple&lt;/strong&gt;: Simulates water ripple effects, creating concentric waves that distort the image&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🎭 Stylization
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7ColorCGASpace&lt;/strong&gt;: Applies a CGA (Color Graphics Adapter) color filter, limiting colors to a retro palette of black, light blue, and purple blocks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Fluctuate&lt;/strong&gt;: Creates a fluctuation effect that distorts the image in a wavelike pattern, similar to graffiti or heat distortion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Glitch&lt;/strong&gt;: Applies a glitch art effect, simulating digital errors such as horizontal displacement and color corruption&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Kuwahara&lt;/strong&gt;: Applies the Kuwahara filter, creating an oil painting effect by averaging pixel values within a neighborhood&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7OilPainting&lt;/strong&gt;: Creates an oil painting effect with brush strokes and texture, simulating the appearance of traditional oil paint&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7RGBADilation&lt;/strong&gt;: Finds the maximum value of each color channel within a specified radius, creating a color expansion effect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7ShiftGlitch&lt;/strong&gt;: Applies an RGB shift glitch effect, separating the red, green, and blue color channels for a trippy appearance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7SoulOut&lt;/strong&gt;: Creates a "soul out" effect, duplicating and offsetting the image to create a ghostly double image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7SplitScreen&lt;/strong&gt;: Creates a split screen effect, dividing the image into multiple sections with different treatments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Storyboard&lt;/strong&gt;: Applies a storyboard effect, giving the image the appearance of a comic book panel&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Toon&lt;/strong&gt;: Creates a cartoon effect with simplified colors and bold outlines, resembling animated characters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7VoronoiOverlay&lt;/strong&gt;: Overlays a Voronoi diagram on the image, creating cellular patterns with sharp edges&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  🎨 Artistic Style Filters
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7PastelDream&lt;/strong&gt;: Creates a soft pastel dream effect with gentle colors, subtle blur, and a warm glow, perfect for creating ethereal, dreamlike images&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7NeonPunk&lt;/strong&gt;: Applies a neon punk effect with vibrant colors, glowing edges, and high contrast, capturing the energetic and rebellious aesthetic of punk culture&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7PaperCut&lt;/strong&gt;: Creates a paper cut art effect with sharp edges, layered appearance, and subtle shadows, simulating the look of intricate paper cut designs&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  🚀 Sci-fi and Futurism Filters
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7Hologram&lt;/strong&gt;: Creates a holographic effect with cyan tint, scan lines, and subtle glitch elements, simulating futuristic holographic displays&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7DigitalGlitch&lt;/strong&gt;: Applies a digital glitch effect with random row offsets, RGB channel separation, and noise, creating the appearance of digital data corruption&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7QuantumDistortion&lt;/strong&gt;: Creates a quantum distortion effect with wave-like pixel offsets, color aberration, and glow, simulating the warping of space-time&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  🌿 Natural and Organic Filters
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7Watercolor&lt;/strong&gt;: Applies a watercolor painting effect with soft edges, color bleeding, and paper texture, capturing the fluid and transparent qualities of watercolor art&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7OrganicGrowth&lt;/strong&gt;: Creates an organic growth effect with noise-based patterns, natural color shifts, and edge enhancement, simulating the appearance of organic forms and textures&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7LensFlare&lt;/strong&gt;: Applies a lens flare effect with light spots, hexagonal artifacts, and color dispersion, simulating the optical flares created by camera lenses&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  📼 Retro and Nostalgic Filters
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7VintageFilmGrain&lt;/strong&gt;: Applies a vintage film grain effect with warm tones, subtle grain noise, desaturation, and vignette, simulating the look of old film stock&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7ComicBook&lt;/strong&gt;: Creates a comic book style effect with bold black outlines, color quantization, and high contrast, resembling hand-drawn comic book art&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C780sSynthwave&lt;/strong&gt;: Applies an 80s synthwave effect with neon colors, purple-blue tint, high contrast, and subtle glow, capturing the nostalgic aesthetic of 1980s synthwave culture&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  📷 Camera Style Filters
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7FujiNC&lt;/strong&gt;: Simulates Fuji film NC style, natural colors, suitable for portraits and daily shooting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7FujiNN&lt;/strong&gt;: Simulates Fuji film NN style, high contrast black and white effect, suitable for documentary and art photography&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7FujiFlash&lt;/strong&gt;: Simulates Fuji film flash mode, bright and transparent, suitable for sunny and outdoor scenes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7FujiX100V&lt;/strong&gt;: Simulates Fuji X100V camera style, classic vintage tone, suitable for street and humanistic photography&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7FujiCC&lt;/strong&gt;: Simulates Fuji Classic Chrome style, low saturation high texture, suitable for landscape and architectural photography&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7RicohPositive&lt;/strong&gt;: Simulates Ricoh positive film style, vibrant colors, rich layers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7RicohNegative&lt;/strong&gt;: Simulates Ricoh negative film style, high contrast, rich dark details&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Universal400&lt;/strong&gt;: Simulates universal 400 film style, strong adaptability, suitable for various scenes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CPM35&lt;/strong&gt;: Simulates CPM35 film style, warm vintage, suitable for portraits and street photography&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Polaroid&lt;/strong&gt;: Simulates Polaroid camera style, with border effect, vintage and cute&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  🌅 Scene Style Filters
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7DarkToneEnhance&lt;/strong&gt;: Enhances dark tone colors, improves picture layering, suitable for low light environment shooting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Sunset&lt;/strong&gt;: Simulates warm tone effect at sunset, suitable for黄昏 and sunrise scenes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7GrayRemoval&lt;/strong&gt;: Removes picture haze, brightens and whitens, suitable for cloudy and hazy weather shooting&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  📊 Matrix Processing
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7ColorMatrix4x4&lt;/strong&gt;: Applies a 4x4 color matrix transformation to the image, allowing for complex color adjustments and transformations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7ColorMatrix4x5&lt;/strong&gt;: Applies a 4x5 color matrix transformation, providing an additional offset value for more flexible color adjustments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7ColorVector4&lt;/strong&gt;: Applies a 4D color vector transformation, modifying the red, green, blue, and alpha components of the image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7ConvolutionMatrix3x3&lt;/strong&gt;: Applies a 3x3 convolution matrix to the image, useful for edge detection, sharpening, and other image processing operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7EdgeGlow&lt;/strong&gt;: Detects edges in the image and adds a glow effect to them, creating a dramatic, outlined appearance&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🎛️ Utility
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7ChromaKey&lt;/strong&gt;: Removes the background that matches a specified color, similar to green screen effects in video production&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7DepthLuminance&lt;/strong&gt;: Adjusts luminance based on depth information, creating a more realistic lighting effect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Highlights&lt;/strong&gt;: Specifically adjusts only the highlight areas of the image, brightening or darkening them as needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7HighlightShadow&lt;/strong&gt;: Independently adjusts the highlights and shadows of the image, allowing for precise tonal control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7HighlightShadowTint&lt;/strong&gt;: Tints the highlights and shadows of the image with specified colors, creating a color graded appearance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7HighlightShadowTone&lt;/strong&gt;: Comprehensive tone adjustment filter with controls for shadows, highlights, midtones, contrast&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7HighPassSkinSmoothing&lt;/strong&gt;: Performs skin smoothing using frequency separation, preserving details while smoothing skin texture&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Levels&lt;/strong&gt;: Adjusts the image levels, controlling the shadows, midtones, and highlights for better tonal range&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Luminance&lt;/strong&gt;: Extracts the luminance (brightness) component from the image, creating a grayscale representation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7LuminanceRangeReduction&lt;/strong&gt;: Reduces the luminance range of the image, compressing the difference between bright and dark areas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7LuminanceThreshold&lt;/strong&gt;: Applies a threshold to the luminance values, creating a high-contrast black and white image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Shadows&lt;/strong&gt;: Specifically adjusts only the shadow areas of the image, brightening or darkening them as needed&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  📐 Geometric Transform
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7Crop&lt;/strong&gt;: Crops the image to a specified rectangular region, removing unwanted areas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Flip&lt;/strong&gt;: Flips the image horizontally or vertically, creating a mirror image along one axis&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Mirror&lt;/strong&gt;: Creates a mirror effect by duplicating and flipping a portion of the image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Resize&lt;/strong&gt;: Resizes the image to a specified width and height, optionally maintaining aspect ratio&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Rotate&lt;/strong&gt;: Rotates the image by a specified angle, around a center point&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Transform&lt;/strong&gt;: Applies an affine transformation to the image, allowing for rotation, scaling, and translation in a single operation&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🎨 Generators
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7ColorGradient&lt;/strong&gt;: Generates a color gradient, creating a smooth transition between two or more colors, useful for backgrounds or overlays&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7SolidColor&lt;/strong&gt;: Generates a solid color image, useful for backgrounds, masks, or as a base for other effects&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  📋 Lookup Tables
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7ColorCube&lt;/strong&gt;: Applies a 3D LUT (Look-Up Table) from CUBE files, allowing for professional color grading and complex color transformations. Supports multiple initialization methods including from file name, URL, or raw data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7LookupTable&lt;/strong&gt;: Applies a color lookup table (LUT) from image files, used for color grading and stylization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7LookupTable512x512&lt;/strong&gt;: 512x512 color search table filter for high-quality color&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🔗 Combination Effects
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7CombinationBeautiful&lt;/strong&gt;: A beauty combination effect that enhances facial features and skin tone, combining multiple beauty-enhancing filters for a polished appearance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CombinationCinematic&lt;/strong&gt;: A cinematic combination effect that creates a film-like appearance with enhanced contrast, saturation, and subtle vignette&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CombinationModernHDR&lt;/strong&gt;: A modern HDR combination effect that improves dynamic range, enhancing both shadow detail and highlight information&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CombinationSkinSmoothing&lt;/strong&gt;: A skin smoothing combination effect that uses frequency separation to smooth skin while preserving details&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CombinationVintage&lt;/strong&gt;: A vintage combination effect that simulates old film stock with warm tones, subtle grain, and reduced contrast&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🎚️ Other Effects
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7Fade&lt;/strong&gt;: Applies a fade effect to the image, gradually transitioning between the original image and a white overlay&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Grayed&lt;/strong&gt;: Converts the image to grayscale using various methods, including luminosity, average, and desaturation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Haze&lt;/strong&gt;: Applies a haze effect to the image, reducing contrast and adding a foggy or misty appearance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Pow&lt;/strong&gt;: Applies a power function to the image, creating non-linear brightness adjustments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7Vignette&lt;/strong&gt;: Applies a vignette effect that darkens the edges of the image, drawing attention to the center&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7VignetteBlend&lt;/strong&gt;: Applies a vignette effect with multiple blend modes, allowing for different styles of edge darkening&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🖼️ Blit Operations
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;C7CopyRegionBlit&lt;/strong&gt;: Copies a specific region from one texture to another&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7CropBlit&lt;/strong&gt;: Crops the image to a specified region&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C7GenerateMipmapsBlit&lt;/strong&gt;: Generates mipmaps for a texture, useful for efficient downsampling&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🎯 CoreImage Integration
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CIBrightness&lt;/strong&gt;: CoreImage brightness adjustment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIColorControls&lt;/strong&gt;: CoreImage color controls (brightness, contrast, saturation)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIColorCube&lt;/strong&gt;: CoreImage color cube filter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIColorMonochrome&lt;/strong&gt;: CoreImage monochrome effect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIContrast&lt;/strong&gt;: CoreImage contrast adjustment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIExposure&lt;/strong&gt;: CoreImage exposure adjustment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIFade&lt;/strong&gt;: CoreImage fade effect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIGaussianBlur&lt;/strong&gt;: CoreImage Gaussian blur&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIHighlight&lt;/strong&gt;: CoreImage highlight adjustment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CILookupTable&lt;/strong&gt;: CoreImage lookup table filter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CINoiseReduction&lt;/strong&gt;: CoreImage noise reduction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIPhotoEffect&lt;/strong&gt;: CoreImage photo effects (chrome, fade, instant, mono, noir, process, tonal, transfer)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIResizedSmooth&lt;/strong&gt;: CoreImage smooth resizing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CISaturation&lt;/strong&gt;: CoreImage saturation adjustment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIShadows&lt;/strong&gt;: CoreImage shadow adjustment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CISharpen&lt;/strong&gt;: CoreImage sharpening&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CISketch&lt;/strong&gt;: CoreImage sketch effect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CITemperature&lt;/strong&gt;: CoreImage temperature adjustment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIUnsharpMask&lt;/strong&gt;: CoreImage unsharp mask sharpening&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIVignette&lt;/strong&gt;: CoreImage vignette effect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIWhitePoint&lt;/strong&gt;: CoreImage white point adjustment&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ⚡ Metal Performance Shaders
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MPSBoxBlur&lt;/strong&gt;: Metal Performance Shaders box blur&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MPSCanny&lt;/strong&gt;: Metal Performance Shaders Canny edge detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MPSGaussianBlur&lt;/strong&gt;: Metal Performance Shaders Gaussian blur&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MPSHistogram&lt;/strong&gt;: Metal Performance Shaders histogram calculation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MPSMedian&lt;/strong&gt;: Metal Performance Shaders median filter&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Find suggestions：&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Need color adjustment → Check &lt;strong&gt;Color adjustment&lt;/strong&gt; classification&lt;/li&gt;
&lt;li&gt;Need blur effect → View &lt;strong&gt;Blur effect&lt;/strong&gt; classification&lt;/li&gt;
&lt;li&gt;Need to blend layers → View &lt;strong&gt;Mixed Mode&lt;/strong&gt; Classification&lt;/li&gt;
&lt;li&gt;Need artistic style → View &lt;strong&gt;Stylized effect&lt;/strong&gt; classification
Five. Need to deform and twist → Check the classification of &lt;strong&gt;Tortion and deformation&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Edge detection is required → View &lt;strong&gt;Edge and Details&lt;/strong&gt; Classification&lt;/li&gt;
&lt;li&gt;Need geometric transformation → View &lt;strong&gt;Geometric transformation&lt;/strong&gt; classification&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  CocoaPods
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;If you want to import &lt;a href="https://github.com/yangKJ/Harbeth" rel="noopener noreferrer"&gt;&lt;strong&gt;Metal&lt;/strong&gt;&lt;/a&gt; module, you need in your Podfile:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pod 'Harbeth'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Swift Package Manager
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://swift.org/package-manager/" rel="noopener noreferrer"&gt;Swift Package Manager&lt;/a&gt; is a tool for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Xcode 11+ is required to build &lt;a href="https://github.com/yangKJ/Harbeth" rel="noopener noreferrer"&gt;Harbeth&lt;/a&gt; using Swift Package Manager.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To integrate Harbeth into your Xcode project using Swift Package Manager, add it to the dependencies value of your &lt;code&gt;Package.swift&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="nv"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"https://github.com/yangKJ/Harbeth.git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"master"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Remarks
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The general process is almost like this, the Demo is also written in great detail, you can check it out for yourself.🎷&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yangKJ/Harbeth" rel="noopener noreferrer"&gt;&lt;strong&gt;HarbethDemo&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tip: If you find it helpful, please help me with a star. If you have any questions or needs, you can also issue.&lt;/p&gt;

&lt;p&gt;Thanks.🎇&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  About the author
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🎷 &lt;strong&gt;E-mail address: &lt;a href="//yangkj310@gmail.com"&gt;yangkj310@gmail.com&lt;/a&gt; 🎷&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🎸 &lt;strong&gt;GitHub address: &lt;a href="https://github.com/yangKJ" rel="noopener noreferrer"&gt;yangKJ&lt;/a&gt; 🎸&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Buy me a coffee or support me on &lt;a href="https://github.com/sponsors/yangKJ?frequency=one-time&amp;amp;sponsor=yangKJ" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  📞 Technical Support
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Frequently Asked Questions
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Q: Which platforms does Harbeth support?&lt;/strong&gt;&lt;br&gt;
A: Harbeth supports iOS 10.0+, macOS 10.13+, tvOS 12.0+, and watchOS 5.0+.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: How is Harbeth's performance?&lt;/strong&gt;&lt;br&gt;
A: Harbeth is built on Metal, fully leveraging GPU acceleration, which is several times faster than CPU processing, especially suitable for real-time processing scenarios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: How to create custom filters?&lt;/strong&gt;&lt;br&gt;
A: You can create custom filters by implementing the &lt;code&gt;C7FilterProtocol&lt;/code&gt; protocol, or create custom color adjustment filters using LUT files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: What advantages does Harbeth have compared to CoreImage?&lt;/strong&gt;&lt;br&gt;
A: Harbeth provides a cleaner API, more built-in filters, and better performance monitoring functionality. At the same time, Harbeth is also compatible with CoreImage filters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: How to handle memory issues?&lt;/strong&gt;&lt;br&gt;
A: You can limit Harbeth's memory usage by adjusting the &lt;code&gt;memoryLimitMB&lt;/code&gt; property, or use asynchronous processing to avoid memory peaks.&lt;/p&gt;

&lt;p&gt;
  &lt;em&gt;Thank you for using Harbeth! I hope it can help with your projects.&lt;/em&gt;
&lt;/p&gt;

</description>
      <category>ios</category>
      <category>performance</category>
      <category>showdev</category>
      <category>swift</category>
    </item>
    <item>
      <title>Automatically generate componentized modules</title>
      <dc:creator>Condy</dc:creator>
      <pubDate>Thu, 03 Feb 2022 14:27:55 +0000</pubDate>
      <link>https://dev.to/yangkj/automatically-generate-componentized-modules-2eji</link>
      <guid>https://dev.to/yangkj/automatically-generate-componentized-modules-2eji</guid>
      <description>&lt;h1&gt;
  
  
  PT
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;👌. Automatically generate componentized modules&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;自动生成组件化模块
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pod lib create Demo swift --template-url='git@github.com:yangKJ/PT'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Swift
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;cd 任意目录文件&lt;/li&gt;
&lt;li&gt;自动快捷创建Swift组件模块，终端执行如下命令&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  pod lib create Demo swift --template-url="&lt;a href="https://github.com/yangKJ/PT"&gt;https://github.com/yangKJ/PT&lt;/a&gt;"
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;将上述&lt;strong&gt;&lt;code&gt;Demo&lt;/code&gt;&lt;/strong&gt;换成对应工程名即可 ⚠️&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;亦或者执行此命令也可 👒👒&lt;/p&gt;

&lt;p&gt;pod lib create Demo swift --template-url='&lt;a href="mailto:git@github.com"&gt;git@github.com&lt;/a&gt;:yangKJ/PT'&lt;/p&gt;
&lt;/blockquote&gt;




&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tip: 该模块会引入默认MVVM + RxSwift响应式架构模块&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;关于该模块架构更多信息，请查看文档.🎷&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yangKJ/WhaleFull"&gt;WhaleFullDemo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you find it helpful, please help me with a star. If you have any questions or needs, you can also issue.&lt;/p&gt;

&lt;p&gt;Thanks.🎇&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Contents
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;自动生成组件化模块目录结构如下，该区域删除或者增加模块&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qswagf79--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/v1/screenshots/template.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qswagf79--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/v1/screenshots/template.png" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  About the author
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🎷 &lt;strong&gt;E-mail address: &lt;a href="//yangkj310@gmail.com"&gt;yangkj310@gmail.com&lt;/a&gt; 🎷&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🎸 &lt;strong&gt;GitHub address: &lt;a href="https://github.com/yangKJ"&gt;yangKJ&lt;/a&gt; 🎸&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  LICENSE
&lt;/h3&gt;

&lt;p&gt;LICENSE is available under the &lt;a href="https://dev.toLICENSE"&gt;MIT&lt;/a&gt; license. See the &lt;a href="https://dev.toLICENSE"&gt;LICENSE&lt;/a&gt; file for more info.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Player</title>
      <dc:creator>Condy</dc:creator>
      <pubDate>Thu, 03 Feb 2022 14:27:00 +0000</pubDate>
      <link>https://dev.to/yangkj/player-4h8</link>
      <guid>https://dev.to/yangkj/player-4h8</guid>
      <description>&lt;p&gt;🎸- Good News, &lt;strong&gt;audio and video player&lt;/strong&gt; has undergone a major revision 2.0&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;English&lt;/strong&gt; | &lt;a href="//README.md"&gt;&lt;strong&gt;简体中文&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️This project has been replaced by the &lt;code&gt;swift&lt;/code&gt; project, &lt;/p&gt;

&lt;p&gt;Please check &lt;a href="https://github.com/yangKJ/KJPlayerDemo/tree/2.1.11"&gt;&lt;strong&gt;KJPlayerDemo-OC&lt;/strong&gt;&lt;/a&gt; for the Object-C version.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;a id="Feature introduction"&gt;&lt;/a&gt; Feature introduction
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Dynamic switching of the core, support for the player program of the side-to-play&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support audio/video playback, midi file playback.&lt;/li&gt;
&lt;li&gt;Support online play and local play.&lt;/li&gt;
&lt;li&gt;Support background playback, audio extraction and playback.&lt;/li&gt;
&lt;li&gt;Support video side-by-side play, segmented download, play and store.&lt;/li&gt;
&lt;li&gt;Support breakpoint resuming and resuming playback, next time it is directly read and played from the buffer.&lt;/li&gt;
&lt;li&gt;Support cache management, clear time period cache.&lt;/li&gt;
&lt;li&gt;Support free look limit, automatically skip the opening and ending credits.&lt;/li&gt;
&lt;li&gt;Support recording the last playing time.&lt;/li&gt;
&lt;li&gt;Support auto play, auto continuous play.&lt;/li&gt;
&lt;li&gt;Support random/repeat/sequential playback.&lt;/li&gt;
&lt;li&gt;Support gravity sensor, full screen/half screen switch.&lt;/li&gt;
&lt;li&gt;Support basic gesture operation, progress volume, etc.&lt;/li&gt;
&lt;li&gt;Support lock screen.&lt;/li&gt;
&lt;li&gt;Long press to fast forward and rewind and other operations.&lt;/li&gt;
&lt;li&gt;Support double speed playback.&lt;/li&gt;
&lt;li&gt;Support switching between different resolution videos.&lt;/li&gt;
&lt;li&gt;Support live streaming media playback.&lt;/li&gt;
&lt;li&gt;Continuously updating...&lt;/li&gt;
&lt;/ul&gt;




&lt;blockquote&gt;
&lt;p&gt;Video support formats: mp4, m3u8, wav, avi, etc.&lt;br&gt;&lt;br&gt;
Audio support formats: midi, mp3, etc.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Free look feature
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This function is similar to the viewing nature of Vip members, and the viewing mode will continue to be played after recharging
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// MARK: - KJPlayerFreeDelegate
extension DetailsViewController: KJPlayerFreeDelegate {

    /// Get free look time
    /// - Parameter player: player core
    /// - Returns: try to see the time, return zero without limit
    func kj_freeLookTime(with player: KJBasePlayer) -&amp;gt; TimeInterval {
        return 50
    }

    /// Free viewing time has ended
    func kj_freeLookTime(with player: KJBasePlayer, currentTime: TimeInterval) {

    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Restore viewing rights after top-up
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;self.player.kj_closeFreeLookTimeLimit()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  CocoaPods installation free look module
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pod 'KJPlayer/FreeTime' # vip try to watch function
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Skip opening and ending credits function
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This function is clearly similar to skip the opening and ending credits when watching a video
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// MARK: - KJPlayerSkipDelegate
extension DetailsViewController: KJPlayerSkipDelegate {

    /// Get the opening time of the beginning of the play
    func kj_skipOpeningTime(with player: KJBasePlayer) -&amp;gt; TimeInterval {
        return 18
    }

    /// Skip opening begin play response
    func kj_skipOpeningTime(with player: KJBasePlayer, openingTime: TimeInterval) {
        self.backview.hintTextLayer.kj_displayHintText("Skip opening intro, automatically play",
                                                       time: 5,
                                                       position: KJPlayerHintPositionBottom)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  CocoaPods installation skip the opening and ending module
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pod 'KJPlayer/SkipTime' # vip skip opening and ending credits function
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Record played time function
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This function will automatically record the last playing time and continue playing seamlessly next time
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// MARK: - KJPlayerRecordDelegate
extension DetailsViewController: KJPlayerRecordDelegate {

    /// Get whether the response needs to be recorded
    func kj_recordTime(with player: KJBasePlayer) -&amp;gt; Bool {
        return true
    }

    /// Get the response to the last play time
    func kj_recordTime(with player: KJBasePlayer, lastTime: TimeInterval) {

    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Actively select storage memory
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;self.player.kj_saveRecordLastTime()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  CocoaPods install automatic record played time module
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pod 'KJPlayer/RecordTime' # vip automatic memory playback function
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Remarks: This function is greater than the skip title function. Simply put, after this function is implemented, it will continue to watch from the last playback position next time.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  CocoaPods Install
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Player modules&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Example import midi player module:
- pod 'KJPlayer/MIDI'

Example import ikj player module:
- pod 'KJPlayer/IJKPlayer'

Example import av player module:
- pod 'KJPlayer/AVPlayer/AVCore'

Example import custom play view module:
- pod 'KJPlayer/CustomView'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Functional area module&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Example import av player play and save module:
- pod 'KJPlayer/AVPlayer/AVDownloader'

Example import record played time:
- pod 'KJPlayer/RecordTime'

Example import free look time:
- pod 'KJPlayer/FreeTime'

Example import skip opening and ending time:
- pod 'KJPlayer/SkipTime'

Example import cache section module:
- pod 'KJPlayer/Cahce'

Example import video screenshot module:
- pod 'KJPlayer/Screenshots'

Example import switch kernel player, 
  Supports 3 kinds of cores, avplayer, midi, ijkplayer
- pod 'KJPlayer/DynamicSource'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Remarks
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The general process is almost like this, the Demo is also written in great detail, you can check it out for yourself.🎷&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yangKJ/KJPlayerDemo"&gt;KJPlayerDemo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tip: The general function is completed, then slowly add other kernels later, if you find it helpful, please help me with a star. If you have any questions or needs, you can also issue.&lt;/p&gt;

&lt;p&gt;Thanks.🎇&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  About the author
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🎷 &lt;strong&gt;E-mail address: &lt;a href="//yangkj310@gmail.com"&gt;yangkj310@gmail.com&lt;/a&gt; 🎷&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🎸 &lt;strong&gt;GitHub address: &lt;a href="https://github.com/yangKJ"&gt;yangKJ&lt;/a&gt; 🎸&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  License
&lt;/h3&gt;

&lt;p&gt;KJPlayer is available under the &lt;a href="https://dev.toLICENSE"&gt;MIT&lt;/a&gt; license. See the &lt;a href="https://dev.toLICENSE"&gt;LICENSE&lt;/a&gt; file for more info.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>MVVM Project Infrastructure</title>
      <dc:creator>Condy</dc:creator>
      <pubDate>Thu, 03 Feb 2022 14:09:09 +0000</pubDate>
      <link>https://dev.to/yangkj/mvvm-project-infrastructure-1opm</link>
      <guid>https://dev.to/yangkj/mvvm-project-infrastructure-1opm</guid>
      <description>&lt;p&gt;&lt;strong&gt;👌. MVVM + RxSwift + CTMediatror + MJRefresh + DZNEmptyDataSet + SkeletonView&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;English | &lt;strong&gt;简体中文&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a set of infrastructure based on &lt;code&gt;MVVM + RxSwift&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Resource module, which mainly deals with image resource and text resource reading.

&lt;ul&gt;
&lt;li&gt;Read image resource: &lt;code&gt;R.image("base_black_back")&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Read text resource: &lt;code&gt;R.text("base_empty_title")&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Adapter
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This module is mainly to encapsulate the base class.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/Rickenbacker"&gt;BaseViewController&lt;/a&gt;: Support oc base class, public part.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/Rickenbacker"&gt;VMTableViewController&lt;/a&gt;: List base class, internally responsive processing.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/Rickenbacker"&gt;VMViewController&lt;/a&gt;: When inheriting this base class, you need to specify &lt;code&gt;ViewModel&lt;/code&gt; or its subclasses as generics.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/Rickenbacker"&gt;ViewModel&lt;/a&gt;: Basic view model.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/Rickenbacker"&gt;TableViewModel&lt;/a&gt;: Mainly used for &lt;code&gt;VMTableViewController&lt;/code&gt; data-driven binding model.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CocoaPods Install ==&amp;gt; &lt;code&gt;pod 'Rickenbacker/Adapter'&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CTMediatror
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This module mainly solves the cocoapods problem encountered by Swift using this componentized solution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CocoaPods Install ==&amp;gt; &lt;code&gt;pod 'Rickenbacker/CTMediatror'&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  HBDNavigationBar
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This module is based on &lt;code&gt;HBDNavigationBar&lt;/code&gt; secondary encapsulation of the underlying basic Navigation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CocoaPods Install ==&amp;gt; &lt;code&gt;pod 'Rickenbacker/HBDNavigationBar'&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  MJRefresh
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This module is based on the refresh function of &lt;code&gt;MJRefresh&lt;/code&gt; encapsulated UITableView.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CocoaPods Install ==&amp;gt; &lt;code&gt;pod 'Rickenbacker/MJRefresh'&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  DZNEmptyDataSet
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This module is based on the empty data display function of the &lt;code&gt;EmptyDataSet-Swift&lt;/code&gt; package UITableView.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CocoaPods Install ==&amp;gt; &lt;code&gt;pod 'Rickenbacker/DZNEmptyDataSet'&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Remarks
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The general process is almost like this, the Demo is also written in great detail, you can check it out for yourself.🎷&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yangKJ/Rickenbacker"&gt;&lt;strong&gt;RickenbackerDemo&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tip: If you find it helpful, please help me with a star. If you have any questions or needs, you can also issue.&lt;/p&gt;

&lt;p&gt;Thanks.🎇&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  About the author
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🎷 &lt;strong&gt;E-mail address: &lt;a href="//yangkj310@gmail.com"&gt;yangkj310@gmail.com&lt;/a&gt; 🎷&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🎸 &lt;strong&gt;GitHub address: &lt;a href="https://github.com/yangKJ"&gt;yangKJ&lt;/a&gt; 🎸&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  License
&lt;/h3&gt;

&lt;p&gt;Rickenbacker is available under the &lt;a href="https://dev.toLICENSE"&gt;MIT&lt;/a&gt; license. See the &lt;a href="https://dev.toLICENSE"&gt;LICENSE&lt;/a&gt; file for more info.&lt;/p&gt;




</description>
    </item>
    <item>
      <title>Network Plugin</title>
      <dc:creator>Condy</dc:creator>
      <pubDate>Thu, 03 Feb 2022 14:06:30 +0000</pubDate>
      <link>https://dev.to/yangkj/network-plugin-support-batch-and-chain-operation-5d8d</link>
      <guid>https://dev.to/yangkj/network-plugin-support-batch-and-chain-operation-5d8d</guid>
      <description>&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/yangKJ/KJNetworkPlugin/blob/master/README.md"&gt;&lt;strong&gt;中文文档&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Network Plugin, support batch and chain operation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Friends who are familiar with swift should know an excellent three party library &lt;a href="https://github.com/Moya/Moya"&gt;Moya&lt;/a&gt;, the plugin version of the network request is really fragrant, so I use the idea to make a pure oc version of the plugin Network request library.&lt;/li&gt;
&lt;li&gt;Friends who are familiar with oc should know an excellent three party library &lt;a href="https://github.com/yuantiku/YTKNetwork"&gt;YTKNetwork&lt;/a&gt;, object based protocol version network request, and then his batch network request and chain network The request is also super fragrant.&lt;/li&gt;
&lt;li&gt;Combining some of the advantages of the two, make a pure OC version of the batch and chain plugin version of the network request library.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Function list
&lt;/h3&gt;

&lt;p&gt;The plugin version of the network request can be more convenient and quick to customize the exclusive network request, and supports batch operation and chain operation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support basic network requests, download and upload files.&lt;/li&gt;
&lt;li&gt;Support configuration of general request and path, general parameters, etc.&lt;/li&gt;
&lt;li&gt;Support batch operation.&lt;/li&gt;
&lt;li&gt;Support chain network request.&lt;/li&gt;
&lt;li&gt;Support setting loading animation plugin.&lt;/li&gt;
&lt;li&gt;Support analysis result plugin.&lt;/li&gt;
&lt;li&gt;Support web cache plugin.&lt;/li&gt;
&lt;li&gt;Support configuration of self built certificate plugin.&lt;/li&gt;
&lt;li&gt;Support to modify the request body and get the response result plugin.&lt;/li&gt;
&lt;li&gt;Support network log packet capture plugin.&lt;/li&gt;
&lt;li&gt;Support refresh to load more plugins.&lt;/li&gt;
&lt;li&gt;Support error code parsing plugin.&lt;/li&gt;
&lt;li&gt;Support error and empty data UI display plugin.&lt;/li&gt;
&lt;li&gt;Support display indicator plugin.&lt;/li&gt;
&lt;li&gt;Support failed error prompt plugin.&lt;/li&gt;
&lt;li&gt;Support request parameter set secret key plugin.&lt;/li&gt;
&lt;li&gt;Support network data unzip and parameter zip plugin.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Network
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;KJBaseNetworking&lt;/strong&gt;: network request base class, based on AFNetworking package use&lt;/p&gt;

&lt;p&gt;&amp;gt; There are also two entrances to set the common root path and common parameters, similar to: userID, token, etc.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/// Root path address
@property (nonatomic, strong, class) NSString *baseURL;
/// Basic parameters, similar to: userID, token, etc.
@property (nonatomic, strong, class) NSDictionary *baseParameters;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&amp;gt; Packaged methods include basic network requests, upload and download files, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KJNetworkingRequest&lt;/strong&gt;: Request body, set network request related parameters, including parameters, request method, plug-ins, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KJNetworkingResponse&lt;/strong&gt;: Respond to the request result, get the data generated between plugins, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KJNetworkingType&lt;/strong&gt;: Summarize all enumerations and callback declarations&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KJNetworkBasePlugin&lt;/strong&gt;: Plugin base class, plugin parent class&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KJNetworkPluginManager&lt;/strong&gt;: Plugin manager, central nervous system&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/// Plugin version network request
/// @param request request body
/// @param success success callback
/// @param failure failure callback
+ (void)HTTPPluginRequest:(KJNetworkingRequest *)request 
                  success:(KJNetworkPluginSuccess)success 
                  failure:(KJNetworkPluginFailure)failure;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;KJNetworkingDelegate&lt;/strong&gt;: Plugin protocol, manage network request results&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Currently, there are 5 protocol methods extracted, starting time, network request time, network success, network failure, and final return&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/// Start preparing for network requests
/// @param request Request related data
/// @param response response data
/// @param endRequest whether to end the following network request
/// @return returns the cached data, successResponse is not empty means there is cached data
- (KJNetworkingResponse *)prepareWithRequest:(KJNetworkingRequest *)request
                                    response:(KJNetworkingResponse *)response
                                  endRequest:(BOOL *)endRequest;

/// Network request start time request
/// @param request Request related data
/// @param response response data
/// @param stopRequest Whether to stop the network request
/// @return Returns the data processed by the plugin at the beginning of the network request
- (KJNetworkingResponse *)willSendWithRequest:(KJNetworkingRequest *)request
                                     response:(KJNetworkingResponse *)response
                                  stopRequest:(BOOL *)stopRequest;

/// Successfully received data
/// @param request receives successful data
/// @param response response data
/// @param againRequest Whether you need to request the network again
/// @return returns the data after successful plugin processing
- (KJNetworkingResponse *)succeedWithRequest:(KJNetworkingRequest *)request
                                    response:(KJNetworkingResponse *)response
                                againRequest:(BOOL *)againRequest;

/// Failure handling
/// @param request failed network activity
/// @param response response data
/// @param againRequest Whether you need to request the network again
/// @return returns the data processed by the failed plugin
- (KJNetworkingResponse *)failureWithRequest:(KJNetworkingRequest *)request
                                    response:(KJNetworkingResponse *)response
                                againRequest:(BOOL *)againRequest;

/// Ready to return to the business logic call at the moment
/// @param request Request related data
/// @param response response data
/// @param error error message
/// @return returns the data after final processing
- (KJNetworkingResponse *)processSuccessResponseWithRequest:(KJNetworkingRequest *)request
                                                   response:(KJNetworkingResponse *)response
                                                      error:(NSError **)error;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Plugins collection
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;There are 13 plugins available for you to use:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="//Docs/LOADING.md"&gt;&lt;strong&gt;KJNetworkLoadingPlugin&lt;/strong&gt;&lt;/a&gt;: Loading animation plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="//Docs/ANSLYSIS.md"&gt;&lt;strong&gt;KJNetworkAnslysisPlugin&lt;/strong&gt;&lt;/a&gt;: Anslysis data plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="//Docs/CACHE.md"&gt;&lt;strong&gt;KJNetworkCachePlugin&lt;/strong&gt;&lt;/a&gt;: Cache plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="//Docs/CERTIFICATE.md"&gt;&lt;strong&gt;KJNetworkCertificatePlugin&lt;/strong&gt;&lt;/a&gt;: Configure certificate plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="//Docs/THIEF.md"&gt;&lt;strong&gt;KJNetworkThiefPlugin&lt;/strong&gt;&lt;/a&gt;: Modifier plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="//Docs/CAPTURE.md"&gt;&lt;strong&gt;KJNetworkCapturePlugin&lt;/strong&gt;&lt;/a&gt;: Network log packet capture plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="//Docs/CODE.md"&gt;&lt;strong&gt;KJNetworkCodePlugin&lt;/strong&gt;&lt;/a&gt;: Error code analysis plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="//Docs/REFRESH.md"&gt;&lt;strong&gt;KJNetworkRefreshPlugin&lt;/strong&gt;&lt;/a&gt;: Refresh to load more plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="//Docs/EMPTY.md"&gt;&lt;strong&gt;KJNetworkEmptyPlugin&lt;/strong&gt;&lt;/a&gt;: Empty data UI display plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="//Docs/INDICATOR.md"&gt;&lt;strong&gt;KJNetworkIndicatorPlugin&lt;/strong&gt;&lt;/a&gt;: Indicator plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="//Docs/WARNING.md"&gt;&lt;strong&gt;KJNetworkWarningPlugin&lt;/strong&gt;&lt;/a&gt;: Failed error prompt plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="//Docs/SECRET.md"&gt;&lt;strong&gt;KJNetworkSecretPlugin&lt;/strong&gt;&lt;/a&gt;: Secret key plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="//Docs/ZIP.md"&gt;&lt;strong&gt;KJNetworkZipPlugin&lt;/strong&gt;&lt;/a&gt;: Unzip plugin&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Chain
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Chained network requests are actually mainly used to manage network requests with interdependencies, and it can actually eventually be used to manage multiple topologically sorted network requests.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Test the chained network request
- (void)testChainNetworking{
    XCTestExpectation * expectation = [self expectationWithDescription:@"test chain."];

    KJNetworkingRequest * request = [[KJNetworkingRequest alloc] init];
    request.method = KJNetworkRequestMethodGET;
    request.ip = @"https://www.httpbin.org";
    request.path = @"/ip";
    request.responseSerializer = KJSerializerJSON;

    [KJNetworkChainManager HTTPChainRequest:request failure:^(NSError *error) {
        XCTFail(@"%@", error.localizedDescription);
    }]
    .chain(^__kindof KJNetworkingRequest * _Nullable(id _Nonnull responseObject) {
        KJNetworkingRequest * request = [[KJNetworkingRequest alloc] init];
        request.ip = @"https://www.httpbin.org";
        request.path = @"/post";
        request.params = {
            "ip": responseObject["origin"]
        };
        return request;
    })
    .lastChain(^(id _Nonnull responseObject) {
        [expectation fulfill];
    });

    [self waitForExpectationsWithTimeout:300 handler:nil];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;a href="//Docs/CHAIN.md"&gt;&lt;strong&gt;More about chained plugin network processing.👒👒&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Batch
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Regarding batch network requests, provide configuration information such as setting the maximum concurrent number, the number of failed calls, and the timing of error reconnection.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Test batch network requests
- (void)testBatchNetworking{
    XCTestExpectation * expectation = [self expectationWithDescription:@"test batch."];

    NSMutableArray * array = [NSMutableArray array];
    {
        KJNetworkingRequest * request = [[KJNetworkingRequest alloc] init];
        request.method = KJNetworkRequestMethodGET;
        request.path = @"/headers";
        request.responseSerializer = KJSerializerJSON;
        [array addObject:request];
    }{
        KJNetworkingRequest * request = [[KJNetworkingRequest alloc] init];
        request.method = KJNetworkRequestMethodGET;
        request.path = @"/ip";
        [array addObject:request];
    }

    KJBatchConfiguration *configuration = [KJBatchConfiguration sharedBatch];
    configuration.maxQueue = 3;
    configuration.requestArray = array.mutableCopy;

    [KJNetworkBatchManager HTTPBatchRequestConfiguration:configuration reconnect:^BOOL(NSArray&amp;lt;KJNetworkingRequest *&amp;gt; * _Nonnull reconnectArray) {
        return YES;
    } complete:^(NSArray&amp;lt;KJBatchResponse *&amp;gt; * _Nonnull result) {
        [expectation fulfill];
    }];

    [self waitForExpectationsWithTimeout:300 handler:nil];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;a href="//Docs/CHAIN.md"&gt;&lt;strong&gt;More about batch plugin network processing.👒👒&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  About the author
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🎷 &lt;strong&gt;E-mail address: &lt;a href="//yangkj310@gmail.com"&gt;yangkj310@gmail.com&lt;/a&gt; 🎷&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🎸 &lt;strong&gt;GitHub address: &lt;a href="https://github.com/yangKJ"&gt;yangKJ&lt;/a&gt; 🎸&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  License
&lt;/h3&gt;

&lt;p&gt;KJNetworkPlugin is available under the &lt;a href="https://dev.toLICENSE"&gt;MIT&lt;/a&gt; license. See the &lt;a href="https://dev.toLICENSE"&gt;LICENSE&lt;/a&gt; file for more info.&lt;/p&gt;

&lt;h3&gt;
  
  
  Link
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/yangKJ/KJNetworkPlugin"&gt;KJNetworkPluginDemo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>iOS Development tools</title>
      <dc:creator>Condy</dc:creator>
      <pubDate>Thu, 03 Feb 2022 14:02:38 +0000</pubDate>
      <link>https://dev.to/yangkj/ios-the-development-tools-43go</link>
      <guid>https://dev.to/yangkj/ios-the-development-tools-43go</guid>
      <description>&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--exOg267A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5ce8643f68c74fc2be80b22204268f65%7Etplv-k3u1fbpfcp-watermark.image%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--exOg267A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5ce8643f68c74fc2be80b22204268f65%7Etplv-k3u1fbpfcp-watermark.image%3F" width="880" height="545"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Set of &lt;strong&gt;Extensions&lt;/strong&gt; and &lt;strong&gt;Custom control&lt;/strong&gt; for standard types and classes.&lt;br&gt;&lt;br&gt;
Just like Doraemon’s pocket, has an endless variety of props for us to use.&lt;/p&gt;

&lt;p&gt;English | &lt;a href="https://github.com/yangKJ/KJCategories/blob/master/README_CN.md"&gt;简体中文&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yangKJ/KJCategories"&gt;KJCategoriesDemo&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[x] OpenCV: Hough correction, feature extraction, image processing package, morphological processing, filter processing, photo restoration, etc.&lt;/li&gt;
&lt;li&gt;[x] NSArray: Related processing of the elements in the array, etc.&lt;/li&gt;
&lt;li&gt;[x] NSDate: Time transformation, etc.&lt;/li&gt;
&lt;li&gt;[x] UIButton: Emitter animation, image and text mixing, click event encapsulation, expanded click field, time interval limit, countdown, click particle effect, etc.&lt;/li&gt;
&lt;li&gt;[x] UIView: Gesture package, rounded corner gradient, Xib attribute, basic animation package, etc.&lt;/li&gt;
&lt;li&gt;[x] UITextView: Expand the input box, limit the number of words, cancel processing, get the internal hyperlink of the text, etc.&lt;/li&gt;
&lt;li&gt;[x] UITextField: Placeholder color, line, graphic processing, etc.&lt;/li&gt;
&lt;li&gt;[x] UILabel: Rich text, fast display text position, etc.&lt;/li&gt;
&lt;li&gt;[x] UIImage: Screenshot and cropping, image compression, mask processing, image stitching, image size processing, filter rendering, flooding algorithm, etc.&lt;/li&gt;
&lt;li&gt;[x] UIImage: QR code, barcode generation, dynamic image playback, watermark processing, etc.&lt;/li&gt;
&lt;li&gt;[x] NSObject: GCD, asynchronous timer, resident thread, thread keep alive, runtime methods, etc.&lt;/li&gt;
&lt;li&gt;[x] NSString: Hash crypto, mathematical operators, unit conversion, etc.&lt;/li&gt;
&lt;li&gt;[x] Other: Gradient slider, Open screen particle animation, projection and shadow, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Encapsulation exception Handling &lt;a href="https://github.com/yangKJ/KJExceptionDemo"&gt;KJExceptionDemo&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  Quick creation of chained UI controls &lt;a href="https://github.com/yangKJ/ChainThen"&gt;ChainThen&lt;/a&gt;
&lt;/h5&gt;

&lt;h3&gt;
  
  
  &lt;a id="Catalogue list"&gt;&lt;/a&gt;Catalogue list
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;OpenCV&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NSArray&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NSDate&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NSDictionary&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NSObject&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NSString&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UIButton&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UIColor&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UIDevice&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UIImage&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UILabel&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UISlider&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UITextField&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UITextView&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UIView&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UIViewController&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Methods and Functions
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;a id="OpenCV"&gt;&lt;/a&gt;OpenCV
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Opencv picture processing.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Signatures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Picture Tile&lt;/td&gt;
&lt;td&gt;kj_opencvTiledRows:cols:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Four-point perspective image based on perspective&lt;/td&gt;
&lt;td&gt;kj_opencvWarpPerspectiveWithKnownPoints:size:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Eliminate image highlights&lt;/td&gt;
&lt;td&gt;kj_opencvIlluminationChangeBeta:alpha:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Picture Blending&lt;/td&gt;
&lt;td&gt;kj_opencvBlendImage:alpha:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adjust picture brightness and contrast&lt;/td&gt;
&lt;td&gt;kj_opencvChangeContrast:luminance:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modify the color of the picture channel value&lt;/td&gt;
&lt;td&gt;kj_opencvChangeR:g:b:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blur processing&lt;/td&gt;
&lt;td&gt;kj_opencvBlurX:y:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gaussian Blur&lt;/td&gt;
&lt;td&gt;kj_opencvGaussianBlurX:y:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Median Blur&lt;/td&gt;
&lt;td&gt;kj_opencvMedianBlurksize:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gaussian Bilateral Blur&lt;/td&gt;
&lt;td&gt;kj_opencvBilateralFilterBlurRadio:sigma:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom linear blur&lt;/td&gt;
&lt;td&gt;kj_opencvCustomBlurksize:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Morphology operations&lt;/td&gt;
&lt;td&gt;kj_opencvMorphology:element:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remove watermark&lt;/td&gt;
&lt;td&gt;kj_opencvInpaintImage:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Picture repair, effect enhancement processing&lt;/td&gt;
&lt;td&gt;kj_opencvRepairImage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cut out the largest inner rectangular area&lt;/td&gt;
&lt;td&gt;kj_opencvCutMaxRegionImage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Feature extraction&lt;/td&gt;
&lt;td&gt;kj_opencvFeatureExtractionFromSobel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hough line judgment and correction&lt;/td&gt;
&lt;td&gt;kj_opencvHoughLinesCorrectTextImageFillColor:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;☝ &lt;strong&gt;Return to the catalogue list&lt;/strong&gt; ☝&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a id="NSArray"&gt;&lt;/a&gt;NSArray
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Related processing of the elements in the array.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Signatures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Is it empty&lt;/td&gt;
&lt;td&gt;isEmpty&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Filter data&lt;/td&gt;
&lt;td&gt;kj_detectArray:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multidimensional array data&lt;/td&gt;
&lt;td&gt;kj_detectManyDimensionArray:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search data&lt;/td&gt;
&lt;td&gt;kj_searchObject:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Map&lt;/td&gt;
&lt;td&gt;kj_mapArray:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insert data to the destination&lt;/td&gt;
&lt;td&gt;kj_insertObject:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Array calculation intersection&lt;/td&gt;
&lt;td&gt;kj_arrayIntersectionWithOtherArray:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Array calculation difference&lt;/td&gt;
&lt;td&gt;kj_arrayMinusWithOtherArray:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Randomly Disorganize Array&lt;/td&gt;
&lt;td&gt;kj_disorganizeArray&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete the same element in the array&lt;/td&gt;
&lt;td&gt;kj_delArrayEquelObj&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Binary Search&lt;/td&gt;
&lt;td&gt;kj_binarySearchTarget:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bubble Sort&lt;/td&gt;
&lt;td&gt;kj_bubbleSort&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insert Sort&lt;/td&gt;
&lt;td&gt;kj_insertSort&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Selection Sort&lt;/td&gt;
&lt;td&gt;kj_selectionSort&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;☝ &lt;strong&gt;Return to the catalogue list&lt;/strong&gt; ☝&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a id="NSDate"&gt;&lt;/a&gt;NSDate
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Time transformation.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Signatures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Convert date to local time&lt;/td&gt;
&lt;td&gt;kj_localeDate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time string conversion NSDate&lt;/td&gt;
&lt;td&gt;kj_dateFromString:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time string to NSDate&lt;/td&gt;
&lt;td&gt;kj_dateFromString:format:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get the current timestamp&lt;/td&gt;
&lt;td&gt;kj_currentTimetampWithMsec:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Timestamp to time&lt;/td&gt;
&lt;td&gt;kj_timeWithTimestamp:format:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get the UTC timestamp of the specified time&lt;/td&gt;
&lt;td&gt;kj_timeStampUTCWithTimeString:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;☝ &lt;strong&gt;Return to the catalogue list&lt;/strong&gt; ☝&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a id="NSDictionary"&gt;&lt;/a&gt;NSDictionary
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Dictionary common methods.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Signatures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Is it empty&lt;/td&gt;
&lt;td&gt;isEmpty&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Convert to Josn String&lt;/td&gt;
&lt;td&gt;jsonString&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Whether to include a key&lt;/td&gt;
&lt;td&gt;kj_containsKey:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dictionary keys in ascending order&lt;/td&gt;
&lt;td&gt;kj_keysSorted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dictionary key name descending order&lt;/td&gt;
&lt;td&gt;kj_keySortDescending&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quickly traverse the dictionary&lt;/td&gt;
&lt;td&gt;kj_applyDictionaryValue:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mapping&lt;/td&gt;
&lt;td&gt;kj_mapDictionary:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merge&lt;/td&gt;
&lt;td&gt;kj_mergeDictionary:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Selector&lt;/td&gt;
&lt;td&gt;kj_pickForKeys:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remover&lt;/td&gt;
&lt;td&gt;kj_omitForKeys:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;☝ &lt;strong&gt;Return to the catalogue list&lt;/strong&gt; ☝&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a id="UIView"&gt;&lt;/a&gt;UIView
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Advanced Edition Rounded Corners and Border Extension.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Signatures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bezier Fillet&lt;/td&gt;
&lt;td&gt;bezierRadius&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shadow Offset&lt;/td&gt;
&lt;td&gt;shadowOffset&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shadow Opacity&lt;/td&gt;
&lt;td&gt;shadowOpacity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shadow Width&lt;/td&gt;
&lt;td&gt;shadowWidth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shadow rounded corners&lt;/td&gt;
&lt;td&gt;shadowRadius&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shadow Color&lt;/td&gt;
&lt;td&gt;shadowColor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Corner Radius&lt;/td&gt;
&lt;td&gt;cornerRadius&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Border Width&lt;/td&gt;
&lt;td&gt;borderWidth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Border Color&lt;/td&gt;
&lt;td&gt;borderColor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image properties&lt;/td&gt;
&lt;td&gt;viewImage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Top Controller&lt;/td&gt;
&lt;td&gt;topViewController&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Current Controller&lt;/td&gt;
&lt;td&gt;viewController&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Current Controller&lt;/td&gt;
&lt;td&gt;kj_currentViewController&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View created by Xib&lt;/td&gt;
&lt;td&gt;kj_viewFromXib&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View created by Xib&lt;/td&gt;
&lt;td&gt;kj_viewFromXibWithFrame:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fillet radius&lt;/td&gt;
&lt;td&gt;kj_radius&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rounded corner orientation&lt;/td&gt;
&lt;td&gt;kj_rectCorner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Border Color&lt;/td&gt;
&lt;td&gt;kj_borderColor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Border width&lt;/td&gt;
&lt;td&gt;kj_borderWidth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Border Orientation&lt;/td&gt;
&lt;td&gt;kj_borderOrientation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Size&lt;/td&gt;
&lt;td&gt;size&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Location&lt;/td&gt;
&lt;td&gt;origin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;x coordinate&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;y coordinate&lt;/td&gt;
&lt;td&gt;y&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Width&lt;/td&gt;
&lt;td&gt;width&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Height&lt;/td&gt;
&lt;td&gt;height&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Center point x&lt;/td&gt;
&lt;td&gt;centerX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Center point y&lt;/td&gt;
&lt;td&gt;centerY&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Left distance&lt;/td&gt;
&lt;td&gt;left&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Right distance&lt;/td&gt;
&lt;td&gt;right&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Top distance&lt;/td&gt;
&lt;td&gt;top&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bottom distance&lt;/td&gt;
&lt;td&gt;bottom&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;x + width&lt;/td&gt;
&lt;td&gt;maxX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;y + height&lt;/td&gt;
&lt;td&gt;Property&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;After Masonry layout x&lt;/td&gt;
&lt;td&gt;masonry_x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;After Masonry layout y&lt;/td&gt;
&lt;td&gt;masonry_y&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Masonry width after layout&lt;/td&gt;
&lt;td&gt;masonry_width&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Masonry height after layout&lt;/td&gt;
&lt;td&gt;masonry_height&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Center the view in its parent view&lt;/td&gt;
&lt;td&gt;kj_centerToSuperview&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Distance from the right of the parent view&lt;/td&gt;
&lt;td&gt;kj_rightToSuperview:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Distance from the bottom of the parent view&lt;/td&gt;
&lt;td&gt;kj_bottomToSuperview:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get the highest Y of the subview&lt;/td&gt;
&lt;td&gt;kj_subviewMaxY&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get the highest X of the subview&lt;/td&gt;
&lt;td&gt;kj_subviewMaxX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Find Subview&lt;/td&gt;
&lt;td&gt;kj_FindSubviewRecursively:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remove all subviews&lt;/td&gt;
&lt;td&gt;kj_removeAllSubviews&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hide/Show all subviews&lt;/td&gt;
&lt;td&gt;kj_hideSubviews:operation:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Child controls handle gesture events&lt;/td&gt;
&lt;td&gt;kj_childHitTest:withEvent:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;☝ &lt;strong&gt;Return to the catalogue list&lt;/strong&gt; ☝&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a id="UITextView"&gt;&lt;/a&gt;UITextView
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;UITextView undo processing, equivalent to command + z, limit processing.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Signatures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Whether to enable the undo function&lt;/td&gt;
&lt;td&gt;kOpenBackout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cancel input&lt;/td&gt;
&lt;td&gt;kj_textViewBackout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Placeholder text&lt;/td&gt;
&lt;td&gt;placeHolder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Placeholder Label&lt;/td&gt;
&lt;td&gt;placeHolderLabel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Limit word count&lt;/td&gt;
&lt;td&gt;limitCount&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Right margin of restricted area&lt;/td&gt;
&lt;td&gt;limitMargin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Restricted area height&lt;/td&gt;
&lt;td&gt;limitHeight&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Statistics limit the number of words Label&lt;/td&gt;
&lt;td&gt;limitLabel&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;☝ &lt;strong&gt;Return to the catalogue list&lt;/strong&gt; ☝&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a id="UITextField"&gt;&lt;/a&gt;UITextField
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;UITextField input box extension, placeholder, quick setting account password box.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Signatures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Set the bottom border line color&lt;/td&gt;
&lt;td&gt;bottomLineColor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Placeholder Color&lt;/td&gt;
&lt;td&gt;placeholderColor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PlaceholderFontSize&lt;/td&gt;
&lt;td&gt;placeholderFontSize&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maximum Length&lt;/td&gt;
&lt;td&gt;maxLength&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clear text to dark text switch&lt;/td&gt;
&lt;td&gt;securePasswords&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maximum character length reached&lt;/td&gt;
&lt;td&gt;kMaxLengthBolck&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text editing moment callback&lt;/td&gt;
&lt;td&gt;kTextEditingChangedBolck&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;☝ &lt;strong&gt;Return to the catalogue list&lt;/strong&gt; ☝&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a id="UILabel"&gt;&lt;/a&gt;UILabel
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;UILabel add long press copy function, Get text position and size.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Signatures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Can copy&lt;/td&gt;
&lt;td&gt;copyable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remove copy long press gesture&lt;/td&gt;
&lt;td&gt;kj_removeCopyLongPressGestureRecognizer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set the display position of the text content&lt;/td&gt;
&lt;td&gt;customTextAlignment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get width&lt;/td&gt;
&lt;td&gt;kj_calculateWidth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get height&lt;/td&gt;
&lt;td&gt;kj_calculateHeightWithWidth:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get height, specify line height&lt;/td&gt;
&lt;td&gt;kj_calculateHeightWithWidth:OneLineHeight:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The text line spacing between Ranges&lt;/td&gt;
&lt;td&gt;kj_AttributedStringTextLineSpace:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text size between ranges&lt;/td&gt;
&lt;td&gt;kj_AttributedStringTextFont:Range:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text color between Ranges&lt;/td&gt;
&lt;td&gt;kj_AttributedStringTextColor:Range:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text size and color between Ranges&lt;/td&gt;
&lt;td&gt;kj_AttributedStringTextFont:TextColor:Range:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text related attributes between Ranges&lt;/td&gt;
&lt;td&gt;kj_AttributedStringTextAttributes:Range:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rich text text size&lt;/td&gt;
&lt;td&gt;kj_AttributedStringTextFont:Loc:Len:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rich text text color&lt;/td&gt;
&lt;td&gt;kj_AttributedStringTextColor:Loc:Len:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rich text text size and color&lt;/td&gt;
&lt;td&gt;kj_AttributedStringTextFont:TextColor:Loc:Len:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rich text related attributes&lt;/td&gt;
&lt;td&gt;kj_AttributedStringTextAttributes:Loc:Len:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;☝ &lt;strong&gt;Return to the catalogue list&lt;/strong&gt; ☝&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a id="UIImage"&gt;&lt;/a&gt;UIImage
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;QR code and barcode generator, image size, screenshot and crop processing, Picture cropper.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Signatures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Convert a string to a barcode&lt;/td&gt;
&lt;td&gt;kj_barCodeImageWithContent:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generate QR Code&lt;/td&gt;
&lt;td&gt;kj_QRCodeImageWithContent:codeImageSize:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generate QR Code with Specified Color&lt;/td&gt;
&lt;td&gt;kj_QRCodeImageWithContent:codeImageSize:color:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generate barcode&lt;/td&gt;
&lt;td&gt;kj_barcodeImageWithContent:codeImageSize:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generate barcode with specified color&lt;/td&gt;
&lt;td&gt;kj_barcodeImageWithContent:codeImageSize:color:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Change the image size, bitmap mode&lt;/td&gt;
&lt;td&gt;kj_bitmapChangeImageSize:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Change the internal pixel color of the image&lt;/td&gt;
&lt;td&gt;kj_changeImagePixelColor:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get network image size&lt;/td&gt;
&lt;td&gt;kj_imageSizeWithURL:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scale the image by scale&lt;/td&gt;
&lt;td&gt;kj_scaleImage:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scale the image with a fixed width&lt;/td&gt;
&lt;td&gt;kj_scaleWithFixedWidth:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scale the image with a fixed height&lt;/td&gt;
&lt;td&gt;kj_scaleWithFixedHeight:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Change the image size proportionally&lt;/td&gt;
&lt;td&gt;kj_cropImageWithAnySize:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reduce the image size proportionally&lt;/td&gt;
&lt;td&gt;kj_zoomImageWithMaxSize:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Do not pull up the filling image&lt;/td&gt;
&lt;td&gt;kj_fitImageWithSize:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Screenshot of the current view&lt;/td&gt;
&lt;td&gt;kj_captureScreen:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Specified location screen capture&lt;/td&gt;
&lt;td&gt;kj_captureScreen:Rect:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customized quality screenshots, quality multiples&lt;/td&gt;
&lt;td&gt;kj_captureScreen:Rect:Quality:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Capture the current screen&lt;/td&gt;
&lt;td&gt;kj_captureScreenWindow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Capture the long image of the scroll view&lt;/td&gt;
&lt;td&gt;kj_captureScreenWithScrollView:ContentOffset:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cut out the transparent part around the picture&lt;/td&gt;
&lt;td&gt;kj_cutImageRoundAlphaZero:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Irregular graphics cutting&lt;/td&gt;
&lt;td&gt;kj_anomalyCaptureImageWithView:BezierPath:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Polygon Cut Image&lt;/td&gt;
&lt;td&gt;kj_polygonCaptureImageWithImageView:PointArray:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Specified area crop&lt;/td&gt;
&lt;td&gt;kj_cutImageWithImage:Frame:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;quartz 2d to achieve cropping&lt;/td&gt;
&lt;td&gt;kj_quartzCutImageWithImage:Frame:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image path clipping, clipping path "outside" part&lt;/td&gt;
&lt;td&gt;kj_captureOuterImage:BezierPath:Rect:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image path clipping, clipping path "within" part&lt;/td&gt;
&lt;td&gt;kj_captureInnerImage:BezierPath:Rect:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Picture Rotation&lt;/td&gt;
&lt;td&gt;kj_rotateInRadians:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Specified color linear blur&lt;/td&gt;
&lt;td&gt;kj_blurImageWithTintColor:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linear blur, keep transparent area&lt;/td&gt;
&lt;td&gt;kj_linearBlurryImageBlur:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blur processing&lt;/td&gt;
&lt;td&gt;kj_blurImageWithRadius:Color:MaskImage:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Equalization calculation&lt;/td&gt;
&lt;td&gt;kj_equalizationImage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Erosion&lt;/td&gt;
&lt;td&gt;kj_erodeImage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Form expansion&lt;/td&gt;
&lt;td&gt;kj_dilateImage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multiple erosion&lt;/td&gt;
&lt;td&gt;kj_erodeImageWithIterations:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multiple expansion of form&lt;/td&gt;
&lt;td&gt;kj_dilateImageWithIterations:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gradient&lt;/td&gt;
&lt;td&gt;kj_gradientImageWithIterations:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Top Hat Computing&lt;/td&gt;
&lt;td&gt;kj_tophatImageWithIterations:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Black Hat Computing&lt;/td&gt;
&lt;td&gt;kj_blackhatImageWithIterations:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Convolution processing&lt;/td&gt;
&lt;td&gt;kj_convolutionImageWithKernel:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sharpen&lt;/td&gt;
&lt;td&gt;kj_sharpenImage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relief&lt;/td&gt;
&lt;td&gt;kj_embossImage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gauss&lt;/td&gt;
&lt;td&gt;kj_gaussianImage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edge Detection&lt;/td&gt;
&lt;td&gt;kj_marginImage&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;☝ &lt;strong&gt;Return to the catalogue list&lt;/strong&gt; ☝&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a id="UIDevice"&gt;&lt;/a&gt;UIDevice
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;UIDevice system related operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Signatures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;App version number&lt;/td&gt;
&lt;td&gt;appCurrentVersion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App Name&lt;/td&gt;
&lt;td&gt;appName&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mobile UUID&lt;/td&gt;
&lt;td&gt;deviceID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get App Icon&lt;/td&gt;
&lt;td&gt;appIcon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get launch page image&lt;/td&gt;
&lt;td&gt;launchImage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;System startup map cache path&lt;/td&gt;
&lt;td&gt;launchImageCachePath&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Launch Image Backup File Path&lt;/td&gt;
&lt;td&gt;launchImageBackupPath&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generate launch image&lt;/td&gt;
&lt;td&gt;kj_launchImageWithPortrait:Dark:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generate launch diagram&lt;/td&gt;
&lt;td&gt;kj_launchImageWithStoryboard:Portrait:Dark:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comparison version number&lt;/td&gt;
&lt;td&gt;kj_comparisonVersion:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jump to the specified URL&lt;/td&gt;
&lt;td&gt;kj_openURL:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Call AppStore&lt;/td&gt;
&lt;td&gt;kj_skipToAppStoreWithAppid:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Call the built-in browser safari&lt;/td&gt;
&lt;td&gt;kj_skipToSafari&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Call the built-in Mail&lt;/td&gt;
&lt;td&gt;kj_skipToMail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Whether to switch to speaker&lt;/td&gt;
&lt;td&gt;kj_changeLoudspeaker:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Save to Album&lt;/td&gt;
&lt;td&gt;kj_savedPhotosAlbumWithImage:Complete:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;System comes with sharing&lt;/td&gt;
&lt;td&gt;kj_shareActivityWithItems:ViewController:Complete:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switch Root View Controller&lt;/td&gt;
&lt;td&gt;kj_changeRootViewController:Complete:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;☝ &lt;strong&gt;Return to the catalogue list&lt;/strong&gt; ☝&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a id="UIColor"&gt;&lt;/a&gt;UIColor
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;UIColor related extension.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Signatures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;UIColor to hexadecimal string&lt;/td&gt;
&lt;td&gt;kj_hexString&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hexadecimal string to UIColor&lt;/td&gt;
&lt;td&gt;kj_colorWithHexString:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;red&lt;/td&gt;
&lt;td&gt;red&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;green&lt;/td&gt;
&lt;td&gt;green&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;blue&lt;/td&gt;
&lt;td&gt;blue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;alpha&lt;/td&gt;
&lt;td&gt;alpha&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hue&lt;/td&gt;
&lt;td&gt;hue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Saturation&lt;/td&gt;
&lt;td&gt;saturation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brightness&lt;/td&gt;
&lt;td&gt;light&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get the RGBA corresponding to the color&lt;/td&gt;
&lt;td&gt;kj_colorGetRGBA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get the average value of colors&lt;/td&gt;
&lt;td&gt;kj_averageColors:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vertical gradient color&lt;/td&gt;
&lt;td&gt;kj_gradientVerticalToColor:height:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Horizontal gradient color&lt;/td&gt;
&lt;td&gt;kj_gradientAcrossToColor:width:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get the color of a specified point on the image&lt;/td&gt;
&lt;td&gt;kj_colorAtImage:Point:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;☝ &lt;strong&gt;Return to the catalogue list&lt;/strong&gt; ☝&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a id="UIButton"&gt;&lt;/a&gt;UIButton
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;UIButton click event block, mixed graphics and text, enlarge click.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Signatures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Add click event&lt;/td&gt;
&lt;td&gt;kj_addAction:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Click Event Interval&lt;/td&gt;
&lt;td&gt;timeInterval&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Expand the unified click field&lt;/td&gt;
&lt;td&gt;enlargeClick&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Graphic style&lt;/td&gt;
&lt;td&gt;layoutType&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Picture and text spacing&lt;/td&gt;
&lt;td&gt;padding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The spacing of the graphic borders&lt;/td&gt;
&lt;td&gt;periphery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Picture and text spacing&lt;/td&gt;
&lt;td&gt;kj_contentLayout:padding:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Picture and text spacing&lt;/td&gt;
&lt;td&gt;kj_contentLayout:padding:periphery:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;☝ &lt;strong&gt;Return to the catalogue list&lt;/strong&gt; ☝&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a id="UISlider"&gt;&lt;/a&gt;UISlider
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Rainbow gradient color slider.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Signatures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Color array&lt;/td&gt;
&lt;td&gt;colors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Location information corresponding to each color&lt;/td&gt;
&lt;td&gt;locations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Color height&lt;/td&gt;
&lt;td&gt;colorHeight&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Border Width&lt;/td&gt;
&lt;td&gt;borderWidth&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Border Color&lt;/td&gt;
&lt;td&gt;borderColor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Callback processing time&lt;/td&gt;
&lt;td&gt;timeSpan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Current progress, for external kvo&lt;/td&gt;
&lt;td&gt;progress&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Moving block&lt;/td&gt;
&lt;td&gt;movingWithTimeSpan:withBlock:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Moved block&lt;/td&gt;
&lt;td&gt;moveEndBlock:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reset UI&lt;/td&gt;
&lt;td&gt;updateUI&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;☝ &lt;strong&gt;Return to the catalogue list&lt;/strong&gt; ☝&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a id="UIViewController"&gt;&lt;/a&gt; UIViewController
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Switch view controller.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Signatures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Jump back to the specified controller&lt;/td&gt;
&lt;td&gt;kj_popTargetViewController:complete:&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switch Root View Controller&lt;/td&gt;
&lt;td&gt;kj_changeRootViewController:&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;☝ &lt;strong&gt;Return to the catalogue list&lt;/strong&gt; ☝&lt;/p&gt;

&lt;h3&gt;
  
  
  CocoaPods Install
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Example import core module:
- pod 'KJCategories'

Example import UIBezierPath:
- pod 'KJCategories/UIKit/UIBezierPath'

Example import NSArray:
- pod 'KJCategories/Foundation/NSArray'

Example import opencv2 picture processing:
- pod 'KJCategories/Opencv'

Example import GradientSlider:
- pod 'KJCategories/Customized/GradientSlider'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  Ex
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Download demo please execute first &lt;code&gt;pod install&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  License
&lt;/h2&gt;

&lt;p&gt;KJCategories is available under the MIT license. See the LICENSE file for more info.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Network API framework</title>
      <dc:creator>Condy</dc:creator>
      <pubDate>Thu, 03 Feb 2022 13:57:38 +0000</pubDate>
      <link>https://dev.to/yangkj/rxswift-moya-handyjson-plugins-netwoek-api-4pm6</link>
      <guid>https://dev.to/yangkj/rxswift-moya-handyjson-plugins-netwoek-api-4pm6</guid>
      <description>&lt;h1&gt;
  
  
  RxNetworks
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;🧚. RxSwift + Moya + HandyJSON + Plugins.👒👒👒&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;English | &lt;a href="//README_CN.md"&gt;&lt;strong&gt;简体中文&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a set of infrastructure based on &lt;code&gt;RxSwift + Moya&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  MoyaNetwork
&lt;/h3&gt;

&lt;p&gt;This module is based on the Moya encapsulated network API architecture.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mainly divided into 8 parts:

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/MoyaNetwork/NetworkConfig.swift"&gt;NetworkConfig&lt;/a&gt;: Set the configuration information at the beginning of the program.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;addDebugging&lt;/strong&gt;：Whether to introduce the debug mode plugin by default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;baseURL&lt;/strong&gt;: Root path address to base URL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;baseParameters&lt;/strong&gt;: Default basic parameters, like: userID, token, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;baseMethod&lt;/strong&gt;: Default request method type.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;updateBaseParametersWithValue&lt;/strong&gt;: Update default base parameter value.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/MoyaNetwork/RxMoyaProvider.swift"&gt;RxMoyaProvider&lt;/a&gt;: Add responsiveness to network requests, returning &lt;code&gt;Single&lt;/code&gt; sequence.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/MoyaNetwork/NetworkUtil.swift"&gt;NetworkUtil&lt;/a&gt;: Network related functions

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;defaultPlugin&lt;/strong&gt;: Add default plugin.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;transformAPIObservableJSON&lt;/strong&gt;: Transforms a &lt;code&gt;Observable&lt;/code&gt; sequence JSON object.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;handyConfigurationPlugin&lt;/strong&gt;: Handles configuration plugins.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/MoyaNetwork/PluginSubType.swift"&gt;PluginSubType&lt;/a&gt;: Inherit and replace the Moya plug-in protocol to facilitate subsequent expansion.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;configuration&lt;/strong&gt;: After setting the network configuration information, this method can be used in scenarios such as throwing data directly when the local cache exists without executing subsequent network requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;lastNever&lt;/strong&gt;: When the last network response is returned, this method can be used in scenarios such as key failure to re-obtain the key and then automatically re-request the network.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/MoyaNetwork/NetworkAPI.swift"&gt;NetworkAPI&lt;/a&gt;: Add protocol attributes and encapsulate basic network requests based on TargetType.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ip&lt;/strong&gt;: Root path address to base URL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;parameters&lt;/strong&gt;: Request parameters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;plugins&lt;/strong&gt;: Set network plugins.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;stubBehavior&lt;/strong&gt;: Whether to take the test data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;retry&lt;/strong&gt;：Network request failure retries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;request&lt;/strong&gt;: Network request method and return a Single sequence object.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/MoyaNetwork/NetworkAPI+Ext.swift"&gt;NetworkAPI+Ext&lt;/a&gt;: Protocol default implementation scheme.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/MoyaNetwork/NetworkAPIOO.swift"&gt;NetworkAPIOO&lt;/a&gt;: OOP converter, MVP to OOP, convenient for friends who are used to OC thinking

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;cdy_ip&lt;/strong&gt;: Root path address to base URL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cdy_path&lt;/strong&gt;: Request path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cdy_parameters&lt;/strong&gt;: Request parameters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cdy_plugins&lt;/strong&gt;: Set network plugins.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cdy_testJSON&lt;/strong&gt;: Network testing json string.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cdy_testTime&lt;/strong&gt;: Network test data return time, the default is half a second.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cdy_HTTPRequest&lt;/strong&gt;: Network request method and return a Single sequence object.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/MoyaNetwork/NetworkX.swift"&gt;NetworkX&lt;/a&gt;: extension function methods etc.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;toJSON&lt;/strong&gt;: to JSON string.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;toDictionary&lt;/strong&gt;: JSON string to dictionary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;+=&lt;/strong&gt;: Dictionary concatenation.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🎷 - OO Example 1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class OOViewModel: NSObject {

    struct Input {
        let retry: Int
    }

    struct Output {
        let items: Observable&amp;lt;String&amp;gt;
    }

    func transform(input: Input) -&amp;gt; Output {
        return Output(items: input.request())
    }
}

extension OOViewModel.Input {
    func request() -&amp;gt; Observable&amp;lt;String&amp;gt; {
        var api = NetworkAPIOO.init()
        api.cdy_ip = NetworkConfig.baseURL
        api.cdy_path = "/ip"
        api.cdy_method = APIMethod.get
        api.cdy_plugins = [NetworkLoadingPlugin()]
        api.cdy_retry = self.retry

        return api.cdy_HTTPRequest()
            .asObservable()
            .compactMap{ (($0 as! NSDictionary)["origin"] as? String) }
            .catchAndReturn("")
            .observe(on: MainScheduler.instance)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎷 - MVP Example 2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enum LoadingAPI {
    case test2(String)
}

extension LoadingAPI: NetworkAPI {
    var ip: APIHost {
        return NetworkConfig.baseURL
    }

    var path: String {
        return "/post"
    }

    var parameters: APIParameters? {
        switch self {
        case .test2(let string): return ["key": string]
        }
    }
}


class LoadingViewModel: NSObject {
    let disposeBag = DisposeBag()
    let data = PublishRelay&amp;lt;NSDictionary&amp;gt;()

    /// Configure the loading animation plugin
    let APIProvider: MoyaProvider&amp;lt;MultiTarget&amp;gt; = {
        let configuration = URLSessionConfiguration.default
        configuration.headers = .default
        configuration.timeoutIntervalForRequest = 30
        let session = Moya.Session(configuration: configuration, startRequestsImmediately: false)
        let loading = NetworkLoadingPlugin.init()
        return MoyaProvider&amp;lt;MultiTarget&amp;gt;(session: session, plugins: [loading])
    }()

    func loadData() {
        APIProvider.rx.request(api: LoadingAPI.test2("666"))
            .asObservable()
            .subscribe { [weak self] (event) in
                if let dict = event.element as? NSDictionary {
                    self?.data.accept(dict)
                }
            }.disposed(by: disposeBag)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎷 - MVVM Example 3:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class CacheViewModel: NSObject {

    struct Input {
        let count: Int
    }

    struct Output {
        let items: Observable&amp;lt;[CacheModel]&amp;gt;
    }

    func transform(input: Input) -&amp;gt; Output {
        let items = request(input.count).asObservable()

        return Output(items: items)
    }
}

extension CacheViewModel {

    func request(_ count: Int) -&amp;gt; Observable&amp;lt;[CacheModel]&amp;gt; {
        CacheAPI.cache(count).request()
            .mapHandyJSON(HandyDataModel&amp;lt;[CacheModel]&amp;gt;.self)
            .compactMap { $0.data }
            .observe(on: MainScheduler.instance) // the result is returned on the main thread
            .catchAndReturn([]) // return null on error
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎷 - Chain Example 4:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ChainViewModel: NSObject {
    let disposeBag = DisposeBag()
    let data = PublishRelay&amp;lt;NSDictionary&amp;gt;()

    func chainLoad() {
        requestIP()
            .flatMapLatest(requestData)
            .subscribe(onNext: { [weak self] data in
                self?.data.accept(data)
            }, onError: {
                print("Network Failed: \($0)")
            }).disposed(by: disposeBag)
    }
}

extension ChainViewModel {
    func requestIP() -&amp;gt; Observable&amp;lt;String&amp;gt; {
        return ChainAPI.test.request()
            .asObservable()
            .map { ($0 as! NSDictionary)["origin"] as! String }
            .catchAndReturn("") // Exception thrown
    }

    func requestData(_ ip: String) -&amp;gt; Observable&amp;lt;NSDictionary&amp;gt; {
        return ChainAPI.test2(ip).request()
            .asObservable()
            .map { ($0 as! NSDictionary) }
            .catchAndReturn(["data": "nil"])
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎷 - Batch Example 5:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class BatchViewModel: NSObject {
    let disposeBag = DisposeBag()
    let data = PublishRelay&amp;lt;NSDictionary&amp;gt;()

    /// Configure loading animation plugin
    let APIProvider: MoyaProvider&amp;lt;MultiTarget&amp;gt; = {
        let configuration = URLSessionConfiguration.default
        configuration.headers = .default
        configuration.timeoutIntervalForRequest = 30
        let session = Moya.Session(configuration: configuration, startRequestsImmediately: false)
        let loading = NetworkLoadingPlugin.init()
        return MoyaProvider&amp;lt;MultiTarget&amp;gt;(session: session, plugins: [loading])
    }()

    func batchLoad() {
        Observable.zip(
            APIProvider.rx.request(api: BatchAPI.test).asObservable(),
            APIProvider.rx.request(api: BatchAPI.test2("666")).asObservable(),
            APIProvider.rx.request(api: BatchAPI.test3).asObservable()
        ).subscribe(onNext: { [weak self] in
            guard var data1 = $0 as? Dictionary&amp;lt;String, Any&amp;gt;,
                  let data2 = $1 as? Dictionary&amp;lt;String, Any&amp;gt;,
                  let data3 = $2 as? Dictionary&amp;lt;String, Any&amp;gt; else {
                      return
                  }
            data1 += data2
            data1 += data3
            self?.data.accept(data1)
        }, onError: {
            print("Network Failed: \($0)")
        }).disposed(by: disposeBag)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  MoyaPlugins
&lt;/h3&gt;

&lt;p&gt;This module is mainly based on moya package network related plugins&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At present, 6 plugins have been packaged for you to use:

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/MoyaPlugins/Cache/NetworkCachePlugin.swift"&gt;Cache&lt;/a&gt;: Network Data Cache Plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/MoyaPlugins/Loading/NetworkLoadingPlugin.swift"&gt;Loading&lt;/a&gt;: Load animation plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/MoyaPlugins/Indicator/NetworkIndicatorPlugin.swift"&gt;Indicator&lt;/a&gt;: Indicator plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/MoyaPlugins/Warning/NetworkWarningPlugin.swift"&gt;Warning&lt;/a&gt;: Network failure prompt plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/MoyaPlugins/Debugging/NetworkDebuggingPlugin.swift"&gt;Debugging&lt;/a&gt;: Network printing, built in plugin&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/MoyaPlugins/GZip/NetworkGZipPlugin.swift"&gt;GZip&lt;/a&gt;: Network data unzip plugin&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🏠 - Simple to use, implement the protocol method in the API protocol, and then add the plugin to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var plugins: APIPlugins {
    let cache = NetworkCachePlugin(cacheType: .networkElseCache)
    let loading = NetworkLoadingPlugin.init(delay: 0.5)
    let warning = NetworkWarningPlugin.init()
    warning.changeHud = { (hud) in
        hud.detailsLabel.textColor = UIColor.yellow
    }
    return [loading, cache, warning]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  HandyJSON
&lt;/h3&gt;

&lt;p&gt;This module is based on &lt;code&gt;HandyJSON&lt;/code&gt; package network data parsing&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Roughly divided into the following 3 parts:

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/HandyJSON/HandyDataModel.swift"&gt;HandyDataModel&lt;/a&gt;: Network outer data model&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/HandyJSON/HandyJSONError.swift"&gt;HandyJSONError&lt;/a&gt;: Parse error related&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangKJ/RxNetworks/blob/master/Sources/HandyJSON/RxHandyJSON.swift"&gt;RxHandyJSON&lt;/a&gt;: HandyJSON data parsing, currently provides two parsing solutions

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Option 1&lt;/strong&gt;: Combine &lt;code&gt;HandyDataModel&lt;/code&gt; model to parse out data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Option 2&lt;/strong&gt;: Parse the data of the specified key according to &lt;code&gt;keyPath&lt;/code&gt;, the precondition is that the json data source must be in the form of a dictionary.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🎷 - Example of use in conjunction with the network part:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func request(_ count: Int) -&amp;gt; Driver&amp;lt;[CacheModel]&amp;gt; {
    CacheAPI.cache(count).request()
        .asObservable()
        .mapHandyJSON(HandyDataModel&amp;lt;[CacheModel]&amp;gt;.self)
        .compactMap { $0.data }
        .observe(on: MainScheduler.instance)
        .delay(.seconds(1), scheduler: MainScheduler.instance)
        .asDriver(onErrorJustReturn: [])
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CocoaPods Install
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ex: Import Network Architecture API
- pod 'RxNetworks/MoyaNetwork'

Ex: Import Model Anslysis 
- pod 'RxNetworks/HandyJSON'

Ex: Import loading animation plugin
- pod 'RxNetworks/MoyaPlugins/Loading'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Remarks
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The general process is almost like this, the Demo is also written in great detail, you can check it out for yourself.🎷&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yangKJ/RxNetworks"&gt;&lt;strong&gt;RxNetworksDemo&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tip: If you find it helpful, please help me with a star. If you have any questions or needs, you can also issue.&lt;/p&gt;

&lt;p&gt;Thanks.🎇&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  About the author
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🎷 &lt;strong&gt;E-mail address: &lt;a href="//yangkj310@gmail.com"&gt;yangkj310@gmail.com&lt;/a&gt; 🎷&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🎸 &lt;strong&gt;GitHub address: &lt;a href="https://github.com/yangKJ"&gt;yangKJ&lt;/a&gt; 🎸&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




</description>
    </item>
  </channel>
</rss>
