<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] # 1. 前言 剛嘗試使用Bitmap的尺寸壓縮來進行圖片大小的設置,但通過設置BitmapFactory.Options.inSampleSize來進行二次加載并沒有達到預想的效果。在之前的[博客](https://blog.csdn.net/qq_26460841/article/details/119785601)中提到: > BitmapFactory.Options類中提供了inSampleSize屬性,如果設置該值大于1,則請求解碼器對原始圖像進行二次采樣,返回較小的圖像以節省內存。樣本大小是任一維度中對應于解碼位圖中單個像素的像素數。例如,inSampleSize=4返回的圖像的寬度/高度為原始圖像的1/4,像素數為1/16。任何小于等于1的值都被視為1。 但是這個尺寸只是像素尺寸,也就是下面的代碼: ~~~ /** * 圖片尺寸壓縮 * @param bitmap 圖片 * @param width 目標寬度 * @param height 目標高度 * @return 壓縮后的圖片 */ fun compressBitmap(bitmap: Bitmap, width: Int, height: Int): Bitmap{ // 裝載Bitmap數據到字節數組 val byteArrayOutputStream = ByteArrayOutputStream() // Write a compressed version of the bitmap to the specified outputstream. bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream) val byteArray = byteArrayOutputStream.toByteArray() // byte[] // 獲取BitmapFactory.Options val options = BitmapFactory.Options() BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size, options) // 設置采樣率 options.inSampleSize = calculateInSampleSize(options, width, height) // 這里需要得到bitmap的實例,故而設置為false options.inJustDecodeBounds = false val tempBitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size, options) return tempBitmap } /** * 計算采樣率 */ private fun calculateInSampleSize(options: BitmapFactory.Options, width: Int, height: Int): Int{ val imgRealWidth = options.outWidth; val imgRealHeight = options.outHeight; var inSampleSize = 1; if(imgRealWidth > width || imgRealHeight > height){ if(imgRealWidth > width){ inSampleSize = Math.round(imgRealWidth.toFloat() / width.toFloat()); // 四舍五入 }else{ inSampleSize = Math.round(imgRealHeight.toFloat() / height.toFloat()); } } return inSampleSize; } ~~~ 上面代碼的應用場景為圖片的大小超過`16MB`,導致不能顯示的問題。但實際上我這里的需求為讓圖片顯示在固定大小的容器中,且隨著容器大小的改變可以自適應。因為在ondraw中直接使用canvas來繪制bitmap圖片就默認按照圖片的原始大小來繪制的。 # 2. 分析 在ImageView中,我們常常可以指定scaleType值來讓ImageView按照默認的縮放類型進行縮放,而這恰好就是我所需要的功能。故而考慮將這個功能copy到自己的自定義View中。 ## 2.1 源碼分析 因為我們設置是在xml配置文件中通過如下的配置進行的: ~~~ <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop"> </ImageView> ~~~ 所以,我們需要在ImageView的構造函數中,找到含有AttributeSet的構造函數,可以看到其解析: ~~~ final int index = a.getInt(R.styleable.ImageView_scaleType, -1); if (index >= 0) { setScaleType(sScaleTypeArray[index]); } ~~~ 對于setScaleType函數: ~~~ public void setScaleType(ScaleType scaleType) { if (scaleType == null) { throw new NullPointerException(); } if (mScaleType != scaleType) { mScaleType = scaleType; requestLayout(); invalidate(); } } ~~~ 主要的部分也就是判斷縮放類型是否和上一個一致,如果不一致就重新賦值。也就是我們這里需要關注mScaleType。進行簡單的源碼文件內搜索,可以看到在configureBounds中對其進行了縮放類型的判斷以及處理,這里簡要摘要: ~~~ private void configureBounds() { if (dwidth <= 0 || dheight <= 0 || ScaleType.FIT_XY == mScaleType) { /* If the drawable has no intrinsic size, or we're told to scaletofit, then we just fill our entire view. */ mDrawable.setBounds(0, 0, vwidth, vheight); mDrawMatrix = null; } else { // We need to do the scaling ourself, so have the drawable // use its native size. mDrawable.setBounds(0, 0, dwidth, dheight); if (ScaleType.MATRIX == mScaleType) { // Use the specified matrix as-is. if (mMatrix.isIdentity()) { mDrawMatrix = null; } else { mDrawMatrix = mMatrix; } } else if (fits) { // The bitmap fits exactly, no transform needed. mDrawMatrix = null; } else if (ScaleType.CENTER == mScaleType) { // Center bitmap in view, no scaling. mDrawMatrix = mMatrix; mDrawMatrix.setTranslate(Math.round((vwidth - dwidth) * 0.5f), Math.round((vheight - dheight) * 0.5f)); } else if (ScaleType.CENTER_CROP == mScaleType) { mDrawMatrix = mMatrix; float scale; float dx = 0, dy = 0; if (dwidth * vheight > vwidth * dheight) { scale = (float) vheight / (float) dheight; dx = (vwidth - dwidth * scale) * 0.5f; } else { scale = (float) vwidth / (float) dwidth; dy = (vheight - dheight * scale) * 0.5f; } mDrawMatrix.setScale(scale, scale); mDrawMatrix.postTranslate(Math.round(dx), Math.round(dy)); } else if (ScaleType.CENTER_INSIDE == mScaleType) { mDrawMatrix = mMatrix; float scale; float dx; float dy; if (dwidth <= vwidth && dheight <= vheight) { scale = 1.0f; } else { scale = Math.min((float) vwidth / (float) dwidth, (float) vheight / (float) dheight); } dx = Math.round((vwidth - dwidth * scale) * 0.5f); dy = Math.round((vheight - dheight * scale) * 0.5f); mDrawMatrix.setScale(scale, scale); mDrawMatrix.postTranslate(dx, dy); } else { // Generate the required transform. mTempSrc.set(0, 0, dwidth, dheight); mTempDst.set(0, 0, vwidth, vheight); mDrawMatrix = mMatrix; mDrawMatrix.setRectToRect(mTempSrc, mTempDst, scaleTypeToScaleToFit(mScaleType)); } } } ~~~ 可以發現其實也就是對mDrawMatrix的一系列變換,包括平移、縮放等。然后在onDraw方法中,也會對應的進行判斷: ~~~ final int saveCount = canvas.getSaveCount(); canvas.save(); if (mCropToPadding) { final int scrollX = mScrollX; final int scrollY = mScrollY; canvas.clipRect(scrollX + mPaddingLeft, scrollY + mPaddingTop, scrollX + mRight - mLeft - mPaddingRight, scrollY + mBottom - mTop - mPaddingBottom); } canvas.translate(mPaddingLeft, mPaddingTop); if (mDrawMatrix != null) { // 對matrix的變換應用到canvas上的所有對象。 canvas.concat(mDrawMatrix); } mDrawable.draw(canvas); canvas.restoreToCount(saveCount); ~~~ 也就是變換其實是Matrix來施加的,最終通過canvas.concat來應用在畫布之上。所以接下來繼續了解Matrix。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看