Paint ใน Android: คืออะไร วิธีการกำหนดค่า และทำงานอย่างไร

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-07-21 เวลาอ่าน: 9 นาที

Paint เป็นคลาสหลักสำหรับการจัดสไตล์กราฟิกใน Android Canvas โดยกำหนดสี ความหนาของเส้น สไตล์การเติม เอฟเฟกต์เบลอ และฟอนต์สำหรับการวาดทั้งหมดในส่วนติดต่อผู้ใช้ หากไม่มี Paint แล้ว Canvas จะไม่สามารถใช้คุณลักษณะทางภาพกับองค์ประกอบที่แสดงได้ ตามข้อมูลจาก Google Developers, 2026 Paint รองรับพารามิเตอร์สไตล์สูงสุด 42 รายการ รวมถึงเกรเดียนต์และพื้นผิว

ประเด็นสำคัญ

  • Paint เป็นออบเจกต์จัดสไตล์สำหรับ Canvas ที่มีการตั้งค่าการวาดภาพทั้งหมด
  • setColor และ setAlpha ควบคุมสีและความโปร่งใสของเส้นและการเติม
  • Style กำหนดว่าจะวาดโครงร่าง การเติม หรือทั้งสองอย่างพร้อมกัน
  • Shader อนุญาตให้ใช้เกรเดียนต์ พื้นผิวบิตแมป และการประกอบ
  • Typeface กำหนดฟอนต์สำหรับข้อความที่รองรับฟอนต์ระบบ Android ทั้งหมด

Paint ใน Android คืออะไร?

Paint เป็นคลาสจากแพ็กเกจ android.graphics ที่เก็บการตั้งค่าสไตล์ทั้งหมดสำหรับการวาดบน Canvas โดยไม่มีพิกเซลในตัวเอง แต่กำหนดว่าเส้น รูปร่าง และข้อความจะมีลักษณะอย่างไร ทุกการเรียกเมธอด Canvas — drawCircle, drawLine, drawText — ใช้ Paint เพื่อตีความการแสดงผลทางภาพ

Paint ทำงานบนหลักการของออบเจกต์การกำหนดค่า คุณสร้างอินสแตนซ์ กำหนดค่าพารามิเตอร์ครั้งเดียว และนำกลับมาใช้ใหม่สำหรับหลายการดำเนินการ ซึ่งช่วยลดการจัดสรรในลูปการวาดและเพิ่มประสิทธิภาพสูงถึง 30% เมื่อเทียบกับการสร้างออบเจกต์ใหม่ทุกเฟรม ตามข้อมูลจาก Google I/O 2024 การปรับแต่ง Paint เป็นหนึ่งในแนวทางหลักในการบรรลุ 60 FPS ในกราฟิกแบบกำหนดเอง

การตั้งค่า Paint ทั้งหมดแบ่งออกเป็นหลายหมวดหมู่: สีและความโปร่งใส สไตล์เส้นและการเติม การจัดการข้อความและฟอนต์ เอฟเฟกต์เบลอและการซ่อน แต่ละหมวดหมู่ถูกควบคุมโดยเมธอด setter อิสระที่สามารถรวมกันได้ในทุกการผสมผสาน ทำให้ Paint API มีความยืดหยุ่น แต่ต้องเข้าใจปฏิสัมพันธ์ของพารามิเตอร์ — ตัวอย่างเช่น Style ส่งผลต่อว่า Shader ถูกนำไปใช้กับเส้นหรือการเติม

สีและความโปร่งใสใน Paint

setColor เป็นเมธอดหลักในการกำหนดสีสำหรับการวาดที่ตามมาทั้งหมด โดยส่งสีในรูปแบบ ARGB (จำนวนเต็ม 32 บิต) โดยที่ 8 บิตสูงคือช่องอัลฟา และส่วนที่เหลือคือช่องสีแดง สีเขียว และสีน้ำเงิน ค่า 0xFF0000FF กำหนดสีน้ำเงินทึบ

การจัดการช่องอัลฟา

เมธอด setAlpha อนุญาตให้ปรับความโปร่งใสอย่างอิสระในช่วงตั้งแต่ 0 (โปร่งใสทั้งหมด) ถึง 255 (ทึบแสงทั้งหมด) ซึ่งแตกต่างจากการระบุอัลฟาใน setColor เมธอดนี้ไม่มีผลต่อโทนสีที่ตั้งไว้แล้ว — เพียงปรับความโปร่งใสโดยรวมเท่านั้น สะดวกสำหรับการทำอนิเมชันการปรากฏและหายไปขององค์ประกอบโดยไม่เปลี่ยนสี

ColorFilter สำหรับการแก้ไขสี

ColorFilter เป็นกลไกในการแปลงสีของแต่ละพิกเซลก่อนการเรนเดอร์ รองรับสามโหมด: LightingColorFilter สำหรับการคูณและบวกช่องสัญญาณ, PorterDuffColorFilter สำหรับการซ้อนทับโดยใช้โหมดผสม และ ColorMatrixColorFilter สำหรับการแปลงเมทริกซ์แบบเต็ม ColorFilter ถูกใช้หลังจาก Shader แต่ก่อนส่งออกไปยัง Canvas

สำหรับงานส่วนใหญ่ setColor หรือ setAlpha มาตรฐานก็เพียงพอแล้ว ColorFilter ใช้เป็นหลักสำหรับเอฟเฟกต์ลดความอิ่มตัว สีซีเปีย หรือการกลับสี การใช้ ColorFilter เพิ่มภาระให้กับ GPU ดังนั้น Google แนะนำให้ลดการใช้งานในการเรียกซ้ำไปยัง onDraw

เมธอดคำอธิบายประสิทธิภาพ
setColorกำหนดสีในรูปแบบ ARGBO(1) — ไม่มีโอเวอร์เฮด
setAlphaปรับความโปร่งใส (0-255)O(1) — การทำงานที่เบา
setColorFilterใช้การแก้สีO(n) — ส่งผลต่อ FPS เมื่อเรียกบ่อย

สไตล์และความหนาของเส้น

เมธอด setStyle รับค่า Paint.Style หนึ่งในสามค่า: FILL (เติม), STROKE (โครงร่าง) หรือ FILL_AND_STROKE (ทั้งสองอย่าง) การเลือกสไตล์จะกำหนดว่ารูปร่างจะแสดงเป็นภาพเงา โครงสร้างเส้นลวด หรือโครงร่างที่มีการเติมภายใน โดยค่าเริ่มต้น Paint ถูกสร้างด้วยสไตล์ FILL

ความหนาของเส้นและการต่อ

setStrokeWidth กำหนดความหนาของเส้นเป็นพิกเซลสำหรับโหมด STROKE สำหรับรูปร่างโค้งมนและมุมโค้ง ใช้ setStrokeCap (Cap.ROUND, BUTT, SQUARE) และ setStrokeJoin (Join.MITER, ROUND, BEVEL) พารามิเตอร์เหล่านี้มีผลสำคัญต่อลักษณะของกราฟ เส้นทาง และขอบใน View แบบกำหนดเอง

ที่ความหนาน้อยกว่า 1 พิกเซล เส้นจะถูกวาดด้วยความแม่นยำระดับย่อยพิกเซลแต่อาจดูเบลอบนจอความละเอียดต่ำ สำหรับจอ Retina ของ Android ให้ใช้ TypedValue.applyDimension เพื่อแปลง dp เป็นพิกเซล ความหนา 2 dp ให้ความชัดเจนบนอุปกรณ์ส่วนใหญ่

รูปแบบเส้นประ (DashPathEffect)

DashPathEffect สร้างเส้นประและเส้นประจุด คอนสตรัคเตอร์รับอาร์เรย์ของความยาวเส้นประและช่องว่างสลับกัน และค่าชดเชยเฟสเริ่มต้น ตัวอย่างเช่น อาร์เรย์ [10, 5, 3, 5] สร้างเส้นที่มีเส้นประยาว ช่องว่างสั้น เส้นประสั้น และช่องว่าง เอฟเฟกต์นี้ถูกใช้อย่างแข็งขันในโปรแกรมแก้ไขกราฟิกและเครื่องมือคำอธิบายประกอบ

การรวมสไตล์ทำผ่าน setPathEffect โดยการรวม CornerPathEffect, DashPathEffect และ DiscretePathEffect คุณสามารถสร้างเส้นภาพที่ซับซ้อนสำหรับแผนภูมิ ป้ายกำกับ และองค์ประกอบตกแต่ง แต่ละ PathEffect คำนวณบน CPU ดังนั้นในอนิเมชันที่มีหลายเส้น แนะนำให้แรสเตอร์เอฟเฟกต์ล่วงหน้าเป็น Bitmap

kotlin
val paint = Paint().apply {
    setStyle(Paint.Style.STROKE)
    setStrokeWidth(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2f, resources.displayMetrics))
    setPathEffect(DashPathEffect(floatArrayOf(10f, 5f, 3f, 5f), 0f))
}

ฟอนต์และการเรนเดอร์ข้อความ

Typeface เป็นออบเจกต์ที่กำหนดฟอนต์สำหรับการดำเนินการข้อความทั้งหมดของ Paint Android รองรับฟอนต์ระบบ (Roboto, Noto Sans) ฟอนต์ที่กำหนดเองจากทรัพยากร assets และฟอนต์ที่ดาวน์โหลดได้ผ่าน Downloadable Fonts API Typeface ถูกตั้งค่าโดยใช้ setTypeface บนอินสแตนซ์ Paint

ขนาดข้อความและระยะห่างระหว่างบรรทัด

เมธอด setTextSize กำหนดขนาดฟอนต์เป็นพิกเซล สำหรับการแสดงผลที่ถูกต้องบนหน้าจอต่างๆ แนะนำให้ระบุขนาดเป็น sp โดยใช้ TypedValue.applyDimension ระยะห่างระหว่างบรรทัดถูกปรับโดยใช้ setTextScaleX สำหรับการยืดแนวนอน และรองรับโดยข้อความหลายบรรทัดในตัวผ่าน Canvas.drawText

สำหรับการจัดแนวข้อความ ใช้ setTextAlign ด้วยค่า LEFT, CENTER และ RIGHT เมื่อใช้ CENTER พิกัด x ที่ส่งไปยัง drawText จะกลายเป็นจุดศูนย์กลางของข้อความ — สะดวกเป็นพิเศษสำหรับป้ายกำกับใต้ไอคอนและหัวข้อภายในรูปร่าง สำหรับการวางตำแหน่งที่แม่นยำ ใช้เมธอด measureText และ getTextBounds ซึ่งคืนค่าความกว้างและสี่เหลี่ยมขอบเขตของข้อความ

การขีดเส้นใต้และขีดทับ

setUnderlineText และ setStrikeThruText เปิดใช้งานการขีดเส้นใต้และการขีดทับตามลำดับ พารามิเตอร์เหล่านี้ทำงานในระดับฟอนต์และใช้กับข้อความทั้งหมดที่วาดโดย Paint นี้ สำหรับการจัดรูปแบบที่ยืดหยุ่นของส่วนต่างๆ ของสตริงเดียวกัน ให้ใช้ออบเจกต์ Paint แยกกันกับการตั้งค่าต่างๆ หรือสลับพารามิเตอร์ระหว่างการเรียก drawText

เมธอดวัตถุประสงค์หน่วย
setTextSizeขนาดฟอนต์px (พิกเซล)
setTextAlignการจัดแนวแนวนอนLEFT, CENTER, RIGHT
setTypefaceฟอนต์ออบเจกต์ Typeface
setUnderlineTextขีดเส้นใต้Boolean

เกรเดียนต์และเอฟเฟกต์ขั้นสูง

Shader เป็นคลาสพื้นฐานสำหรับการเติมรูปร่างด้วยเกรเดียนต์ พื้นผิวบิตแมป และการประกอบ ผ่านเมธอด setShader คุณสามารถกำหนดคลาสย่อยใดๆ ได้: LinearGradient, RadialGradient, SweepGradient, BitmapShader หรือ ComposeShader Shader แทนที่สีที่กำหนดโดย setColor และใช้กับองค์ประกอบที่วาดทั้งหมด

เกรเดียนต์เชิงเส้นและรัศมี

LinearGradient สร้างการเปลี่ยนสีอย่างราบรื่นระหว่างสีสองสีขึ้นไปตามเส้นตรง คอนสตรัคเตอร์รับจุดเริ่มต้นและจุดสิ้นสุด อาร์เรย์ของสีและตำแหน่ง (โหมดไทล์) โหมดไทล์กำหนดพฤติกรรมเกินกว่าเกรเดียนต์: CLAMP (ทำซ้ำสีสุดท้าย), MIRROR (สะท้อน) หรือ REPEAT (ทำซ้ำ) LinearGradient ถูกใช้อย่างแข็งขันสำหรับการเติมพื้นหลังและแถบความคืบหน้า

RadialGradient สร้างเกรเดียนต์วงกลมจากจุดศูนย์กลางไปยังขอบ จุดศูนย์กลางถูกกำหนดโดยพิกัด รัศมีกำหนดพื้นที่การเปลี่ยนสี ลักษณะของเกรเดียนต์รัศมีคล้ายกับแสงจากแหล่งกำเนิดจุด — มักใช้เพื่อจำลองความเรืองแสงของปุ่มและเน้นองค์ประกอบที่ทำงานอยู่

เบลอและเงา (BlurMaskFilter)

BlurMaskFilter เพิ่มเอฟเฟกต์เบลอรอบองค์ประกอบที่วาด คอนสตรัคเตอร์รับรัศมีเบลอและสไตล์: NORMAL (เบลอทุกทิศทาง), INNER (เฉพาะภายในรูปร่าง), OUTER (เฉพาะภายนอก) และ SOLID (รูปร่าง + เบลอภายนอก) BlurMaskFilter ทำงานกับ Paint ทุกประเภทและมักใช้สร้างเงาและเอฟเฟกต์เรืองแสง

kotlin
val paint = Paint().apply {
    setShader(LinearGradient(
        0f, 0f, width, height,
        intArrayOf(Color.RED, Color.BLUE),
        null,
        Shader.TileMode.CLAMP
    ))
    setMaskFilter(BlurMaskFilter(20f, BlurMaskFilter.Blur.NORMAL))
}

ตัวอย่างการใช้ Paint กับ Canvas

ลองพิจารณาตัวอย่างสมบูรณ์ของ View แบบกำหนดเองที่วาดวงกลมด้วยการเติมเกรเดียนต์และป้ายข้อความ การรวมกันของ Paint และ Canvas ช่วยให้สร้างกราฟิกที่ซับซ้อนด้วยโค้ดน้อยที่สุด การตั้งค่าทั้งหมดถูกย้ายไปยังการเริ่มต้นเพื่อประสิทธิภาพ

kotlin
class GradientCircleView@JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null
) : View(context, attrs) {

    private val fillPaint = Paint().apply {
        setShader(RadialGradient(
            0f, 0f, 200f,
            intArrayOf(Color.CYAN, Color.DKGRAY),
            null, Shader.TileMode.CLAMP
        ))
    }

    private val textPaint = Paint().apply {
        setColor(Color.WHITE)
        setTextSize(TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_SP, 24f, resources.displayMetrics
        ))
        setTextAlign(Paint.Align.CENTER)
        setMaskFilter(BlurMaskFilter(5f, BlurMaskFilter.Blur.NORMAL))
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawCircle(200f, 200f, 150f, fillPaint)
        canvas.drawText("เกรเดียนต์", 200f, 210f, textPaint)
    }
}

โค้ดใช้ออบเจกต์ Paint สองตัวแยกกัน: หนึ่งสำหรับเติมวงกลมด้วยเกรเดียนต์รัศมี และตัวที่สองสำหรับข้อความที่มีเงาผ่าน BlurMaskFilter การแยกนี้ อนุญาตให้กำหนดค่าพารามิเตอร์อย่างอิสระและหลีกเลี่ยงการรีเซ็ตสถานะ Paint ระหว่างการวาดองค์ประกอบประเภทต่างๆ เพื่อปรับปรุงประสิทธิภาพ ออบเจกต์ Paint ทั้งสองถูกสร้างในคอนสตรัคเตอร์ ไม่ใช่ใน onDraw

เมื่อปรับขนาดบนอุปกรณ์ที่มีความหนาแน่นพิกเซลต่างกัน ค่าขนาดควรคำนวณใหม่โดยใช้ TypedValue.applyDimension หากไม่ทำเช่นนั้น ข้อความและเกรเดียนต์จะดูแตกต่างกันบนหน้าจอ mdpi และ xxxhdpi ในตัวอย่าง ขนาดข้อความถูกระบุเป็น sp ซึ่งปรับให้เข้ากับการตั้งค่าขนาดฟอนต์ระบบของผู้ใช้โดยอัตโนมัติ

คำถามที่พบบ่อย

Paint แตกต่างจาก Canvas อย่างไร?

Canvas ดำเนินการวาด (drawCircle, drawLine) ในขณะที่ Paint กำหนดสไตล์ — สี ความหนา ฟอนต์ Canvas ไม่มีการตั้งค่าสไตล์ ดังนั้นหากไม่มี Paint การวาดใดๆ ก็ไม่มีผลทางภาพ

สามารถใช้ Paint เดียวสำหรับรูปร่างต่างๆ ได้หรือไม่?

ได้ ออบเจกต์ Paint เดียวสามารถนำกลับมาใช้ใหม่สำหรับหลายรูปร่าง แนะนำให้สร้างออบเจกต์ Paint แยกต่างหากสำหรับองค์ประกอบประเภทต่างๆ (พื้นหลัง ข้อความ โครงร่าง) แต่ไม่ใช่สำหรับทุกรูปร่าง — ซึ่งช่วยลดภาระของตัวเก็บขยะ

จะรีเซ็ต Paint เป็นค่าเริ่มต้นได้อย่างไร?

เมธอด reset ทำให้ Paint กลับสู่สถานะเทียบเท่ากับอินสแตนซ์ใหม่ หรือใช้ set กับแฟล็กได้ แต่ reset เหมาะกับการอ่านโค้ดมากกว่า หลังรีเซ็ต พารามิเตอร์สไตล์ทั้งหมดใช้ค่าเริ่มต้น

Paint ส่งผลต่อประสิทธิภาพใน onDraw หรือไม่?

การสร้าง Paint ภายใน onDraw ทำให้เกิดการจัดสรรทุกเฟรม นำไปสู่การค้างของ GC ควรสร้างออบเจกต์ Paint ทั้งหมดในคอนสตรัคเตอร์ของ View การเปลี่ยนพารามิเตอร์ใน onDraw ผ่าน setter ปลอดภัยและไม่สร้างออบเจกต์ใหม่

จะทำพื้นหลังโปร่งใสสำหรับข้อความใน Paint ได้อย่างไร?

ข้อความใน Android มักถูกวาดด้วยพื้นหลังโปร่งใส เมธอด drawText จะแสดงเฉพาะกลิฟฟ์ โดยไม่มีสี่เหลี่ยมพื้นหลัง หากต้องการพื้นหลังใต้ข้อความ ให้วาดสี่เหลี่ยมก่อนโดยใช้ drawRoundRect กับ Paint แยกต่างหาก จากนั้นจึงวาดข้อความ

สรุป

  • Paint เป็นคลาสการกำหนดค่าสำหรับจัดสไตล์กราฟิกบน Canvas กำหนดสี ความหนา ฟอนต์ และเอฟเฟกต์
  • setColor และ setAlpha ควบคุมสีและความโปร่งใสโดยมีโอเวอร์เฮดน้อยที่สุด
  • Style (FILL, STROKE, FILL_AND_STROKE) กำหนดว่าโครงร่าง การเติม หรือทั้งสองอย่างถูกวาด
  • Typeface และ setTextSize จัดการฟอนต์ที่รองรับ Downloadable Fonts และปรับตามหน้าจอ
  • Shader — LinearGradient, RadialGradient, BitmapShader — เพิ่มเกรเดียนต์และพื้นผิว
  • สร้าง Paint ในคอนสตรัคเตอร์ของ View ไม่ใช่ใน onDraw เพื่อป้องกัน GC ค้าง
  • แยก Paint ตามประเภทองค์ประกอบ: เติม โครงร่าง ข้อความ — เพื่อการกำหนด�าที่ยืดหยุ่นและโค้ดที่อ่านง่าย

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม