iOS 使用矢量圖

来源:http://www.cnblogs.com/silence-cnblogs/archive/2017/08/08/7307554.html
-Advertisement-
Play Games

iOS 使用矢量圖 iOS 圖標通常用 PNG 格式的圖片。PNG 圖片放大到超過自身的大小就會模糊。可以使用 PDF 格式的矢量圖,優點是任意改變圖片大小並且保持清晰度。 簡單使用 與 PNG 格式的圖片一樣,在 Xcode 中把 PDF 格式的矢量圖拖進 \ .xcassets (預設是 Ass ...


iOS 使用矢量圖

iOS 圖標通常用 PNG 格式的圖片。PNG 圖片放大到超過自身的大小就會模糊。可以使用 PDF 格式的矢量圖,優點是任意改變圖片大小並且保持清晰度。

簡單使用

與 PNG 格式的圖片一樣,在 Xcode 中把 PDF 格式的矢量圖拖進 *.xcassets (預設是 Assets.xcassets) 文件夾中,然後用不帶尾碼(.pdf)的文件名生成 UIImage

imageView.image = [UIImage imageNamed:@"Vector"];

註意,如果以上代碼用 "Vector.pdf",無法得到 UIImage。

這樣做的話,Xcode 會在編譯時根據 PDF 圖的大小生成 @1x、@2x、@3x 的 PNG 圖片,與使用 PNG 圖片的顯示效果相同。如果把圖片放大到超過 PNG 圖片的大小,則會顯示模糊的圖片。沒有發揮矢量圖可以任意調整大小的優點。

改變矢量圖大小

如果需要改變矢量圖大小並且保持清晰度,那就要解析 PDF 源文件,把矢量圖繪製成所需大小的點陣圖(Bitmap)。YHPDFImageLoader 庫就實現了這個功能,並且可以選擇拉伸圖片時是否保持原圖寬高比,還添加了記憶體和磁碟緩存。解析 PDF 並繪製點陣圖的代碼在 YHPDFImageDraw.m 文件的 drawImageWithURL:size:canStretched:page: 方法中。但是那些代碼有 bug,在保持原圖寬高比的時候,繪製出的點陣圖不居中。這裡參照那些代碼,寫了 UIImage 的 Category,用於解析 PDF 源文件,繪製指定大小的點陣圖;可以選擇拉伸圖片時是否保持原圖寬高比;拉伸時保持圖片居中。註意,這裡的 PDF 文件放在工程目錄中,與 *.m、*.h 文件一樣,不能放在 *.xcassets 里。

#import "UIImage+Vector.h"

@implementation UIImage (Vector)

+ (UIImage *)vectorImageWithName:(NSString *)name size:(CGSize)size {
    // 預設保持原圖寬高比
    return [self vectorImageWithName:name size:size stretch:NO];
}

+ (UIImage *)vectorImageWithName:(NSString *)name size:(CGSize)size stretch:(BOOL)stretch {
    // PDF 文件路徑
    NSString *path = [NSBundle.mainBundle pathForResource:name ofType:@"pdf"];
    NSAssert(path, @"Vector image file path should NOT be nil");
    if (!path) return nil;
    return [self vectorImageWithURL:[NSURL fileURLWithPath:path] size:size stretch:stretch page:1];
}

// url: PDF 文件 URL
// size: 所需繪製圖片大小;如果需要繪製原圖大小,用 CGSizeZero
// stretch: 是否拉伸;YES,拉伸圖片,忽略原圖寬高比;NO,保持原圖寬高比
+ (UIImage *)vectorImageWithURL:(NSURL *)url size:(CGSize)size stretch:(BOOL)stretch page:(NSUInteger)page {
    
    CGFloat screenScale = UIScreen.mainScreen.scale;
    // PDF 源文件
    CGPDFDocumentRef pdfRef = CGPDFDocumentCreateWithURL((__bridge CFURLRef)url);
    // PDF 中的一頁
    CGPDFPageRef imagePage = CGPDFDocumentGetPage(pdfRef, page);
    // PDF 這一頁顯示出來的 CGRect
    CGRect pdfRect = CGPDFPageGetBoxRect(imagePage, kCGPDFCropBox);
    // 傳入的大小如果為零,使用 PDF 原圖大小
    CGSize contextSize = (size.width <= 0 || size.height <= 0) ? pdfRect.size : size;
    // RGB 顏色空間
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    // 點陣圖上下文
    CGContextRef context = CGBitmapContextCreate(NULL,
                                                 contextSize.width * screenScale,
                                                 contextSize.height * screenScale,
                                                 8,
                                                 0,
                                                 colorSpace,
                                                 kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);
    // 坐標縮放,增加清晰度
    CGContextScaleCTM(context, screenScale, screenScale);
    
    if (size.width > 0 && size.height > 0) {
        // 指定圖片大小,需要縮放圖片
        // 計算寬高縮放比
        CGFloat widthScale = size.width / pdfRect.size.width;
        CGFloat heightScale = size.height / pdfRect.size.height;
        
        if (!stretch) {
            // 保持原圖寬高比,使用寬高縮放比中的最小值
            heightScale = MIN(widthScale, heightScale);
            widthScale = heightScale;
            // 坐標平移,使圖片居中
            CGFloat currentRatio = size.width / size.height;
            CGFloat realRatio = pdfRect.size.width / pdfRect.size.height;
            if (currentRatio < realRatio) {
                CGContextTranslateCTM(context, 0, (size.height - size.width / realRatio) / 2);
            } else {
                CGContextTranslateCTM(context, (size.width - size.height * realRatio) / 2, 0);
            }
        }
        // 用以上寬高縮放比縮放坐標
        CGContextScaleCTM(context, widthScale, heightScale);
        
    } else {
        // 使用原圖大小
        // 獲取原圖坐標轉換矩陣,用於點陣圖上下文
        CGAffineTransform drawingTransform = CGPDFPageGetDrawingTransform(imagePage, kCGPDFCropBox, pdfRect, 0, true);
        CGContextConcatCTM(context, drawingTransform);
    }
    // 把 PDF 中的一頁繪製到點陣圖
    CGContextDrawPDFPage(context, imagePage);
    CGPDFDocumentRelease(pdfRef);
    // 創建 UIImage
    CGImageRef image = CGBitmapContextCreateImage(context);
    UIImage *pdfImage = [[UIImage alloc] initWithCGImage:image scale:screenScale orientation:UIImageOrientationUp];
    // 釋放資源
    CGImageRelease(image);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    
    return pdfImage;
}

@end

使用方法

// 保持原圖寬高比
imageView.image = [UIImage vectorImageWithName:@"Vector" size:CGSizeMake(50, 50)];
// 拉伸圖片,忽略原圖寬高比
imageView.image = [UIImage vectorImageWithName:@"Vector"
                                          size:CGSizeMake(50, 50)
                                       stretch:YES];

參考

http://lugede.cn/ios-use-vector-pdf-image

https://github.com/jiisd/YHPDFImageLoader

轉載請註明出處:http://www.cnblogs.com/silence-cnblogs/p/7307554.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 新建項目 開始(確認已經安裝node環境和npm包管理工具) 1、新建項目文件名為start_vuedemo 2、npm init -y 初始化項目,我的win7系統,工程在d盤的vue_test_project文件夾下的名為start_vuedemo的工程文件夾 如圖所示: 在該工程下自動生成一個 ...
  • 響應式網格系統 ======================================== 響應式網格系統的概念 把網頁劃分成列、行、外邊距、隔離帶(各列與各行之間的空白)等由一系列相交的水平軸和垂直軸組成的網格。 網格佈局的作用在於更有效地控制元素在網頁中所占比例的大小。比如,博客中有一個留 ...
  • 上一篇《Vue開發環境搭建及熱更新》,我們講解了vue開發環境的搭建還有一些小問題,接下來我們來講解一下這個界面是如何形成的。 在開始講之前,我們先來看看我們上一篇所謂的項目目錄裡面到底放著什麼。 1.index.html文件入口 ; 2.src放置組件和入口文件 ; 3.node_modules為 ...
  • 1、color 解析顏色 把代表顏色的字元串轉換為顏色值 2、data-uri 把我們需要使用的素材圖片轉化成BASE64編碼 ,項目中尤其是移動端的項目,節省了圖片的載入時間,是圖片優化的一個手段;LESS對於大圖片是不能轉碼的,我們可以使用BASE64工具轉碼(tool.css-js.com) ...
  • 1.使用cdn引入font_awesome圖標庫的css文件 例如:index.htm <html><head><title>font_awesome test</title><link rel="stylesheet" href="https://cdn.bootcss.com/font-awes ...
  • 這是模塊化開發、主流框架和最新版的ECMAScript語法規範的一個小demo 準備工作 安裝 nodeJs 首先進入node官網,去下載最新版的nodeJs webpack 安裝webpack npm install webpack -g 參數-g表示全局安裝webpack,你在cmd命令中哪個文 ...
  • 當變數為'',false,null,undefined,0,NaN時,返回預設值 "hello world" 0 || 'ccc' "ccc" NaN || 'ccc' "ccc" 我感覺想不通一個問題 '' == false ==>true false == false ==>true null= ...
  • 由於`CoreGraphics`框架有太多的`API`,對於初次接觸或者對該框架不是十分瞭解的人,在繪圖時,對`API`的選擇會感到有些迷茫,甚至會覺得`iOS`的圖形繪製有些繁瑣。因此,本文主要介紹一下`iOS`的繪圖方法和分析一下`CoreGraphics`框架的繪圖原理。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...